作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一些使用类型来消除实例歧义的代码(真正的代码是使用 GHC.TypeLits 单例作为类型标签,但我认为这没有密切关系),我想使用 let 绑定(bind)来避免文本- 级别重复;不幸的是,这使结果单一化。
以下是问题的示例:
class Foo a where
foo :: a
instance Foo Int where
foo = 0
instance Foo Char where
foo = 'a'
data Bar a = Bar String
deriving (Show)
bar :: forall a. (Show a, Foo a) => a -> Bar a
bar _ = Bar $ show (foo :: a)
idInt :: Bar Int -> Bar Int
idInt = id
idChar :: Bar Char -> Bar Char
idChar = id
main = let quux = bar undefined in
print (idInt quux) >> print (idChar quux)
上面的代码无法编译(但是,当然,如果我输入 annotate quux
为多态,一切正常),正确地提示它无法匹配 Int
与 Char
。有什么方法可以让编译成功,而无需类型注释,也无需在每个使用站点重复 bar undefined
?
最佳答案
{-# LANGUAGE NoMonomorphismRestriction #-}
或者如果你想要一些不太全局化的东西
let quux () = bar undefined in
print (idInt (quux ()) >> print (idChar (quux ()))
后者起作用的原因是,只有当等号左侧没有参数时,绑定(bind)才是单态的。
let foo = \x y -> x + y -- :: Integer -> Integer -> Integer
let bar x y = x + y -- :: (Num a) => a -> a -> a
因此,要使 quux 不单态化,您必须在等号左侧为其提供一个参数。如果 quux 不是一个值而是一个函数,您可以简单地进行 eta 扩展以获得相同的效果:
let quux x = bar undefined x in ...
对于前者,不必担心性能 - 如果您始终将其称为 quux ()
,那么它将被内联并生成与具有显式类型签名的版本相同的代码.
关于haskell - 在没有类型注释的情况下避免 let 绑定(bind)中的单态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14657475/
我来自 Asp.Net 世界,试图理解 Angular State 的含义。 什么是 Angular 状态?它类似于Asp.Net中的ascx组件吗?是子页面吗?它类似于工作流程状态吗? 我听到很多人
我一直在寻找 3 态拨动开关,但运气不佳。 基本上我需要一个具有以下状态的开关: |开 |不适用 |关 | slider 默认从中间开始,一旦用户向左或向右滑动,就无法回到N/A(未回答)状态。 有人
我是一名优秀的程序员,十分优秀!