Dan*_*Dan 5 lambda haskell types
我想打号码列表中的每个0.1从-150到150.
为此,我创建了一个列表,然后尝试将Fractional multiplication lambda映射到它上面,如下所示:
let indices = [-1500,-1499..1500]
let grid = map (\x -> 0.1 *x) indices
Run Code Online (Sandbox Code Playgroud)
这使得ghci吐出错误.
另一方面,这两个都很好:
let a = 0.1*2
Run Code Online (Sandbox Code Playgroud)
和
let grid = map (\x -> 2 *x) indices
Run Code Online (Sandbox Code Playgroud)
这里发生了什么?为什么当应用于带有地图的列表时,Num乘以Fractional的乘法才会失败?
编辑:我得到的错误是:
No instance for (Fractional Integer)
arising from the literal `0.1'
Possible fix: add an instance declaration for (Fractional Integer)
In the first argument of `(*)', namely `0.1'
In the expression: 0.1 * x
In the first argument of `map', namely `(\ x -> 0.1 * x)'
Run Code Online (Sandbox Code Playgroud)
kpu*_*nam 10
你已经发现了"可怕的单态限制".基本上GHC将推断的类型indices是一个单型等[Integer]代替Num a => a.您可以提供类似的注释indices :: [Float],也可以重新定义您的定义以避免限制.
例如(不是建议),如果你创建indices一个函数:let indices a = [-1500, -1499..1500],现在是推断类型(Enum t, Num t) => a -> [t].该a参数未使用但违反了限制.然后你就可以了map f (indices whatever).在Haskell Wiki中查看有关Monomorphism Restriction的更多信息.
这是违约.
你的indices变量,而不是Num你所期望的类型类的多态,是默认为Integer,此时你不能将它乘以0.1,因为0.1它将解析为某些Fractional类型.
您可以使用显式类型签名强制索引具有多态性:
let indices :: (Enum a, Num a) => [a]; indices = [-1500,-1499..1500]
Run Code Online (Sandbox Code Playgroud)
虽然在实践中你并不经常想要以这种方式显式的多态列表.
有一个关于haskell维基上的单态限制的页面,虽然它不是特别简洁:http://www.haskell.org/haskellwiki/Monomorphism_restriction