Int和Num类型的haskell
我有下面的代码来采取参数设置一些偏移时间。
setOffsetTime :: (Ord a, Num b)=>[a] -> b
setOffsetTime [] = 200
setOffsetTime (x:xs) = read x::Int
但编译器说:“ 无法从由setOffsetTime ::(Ord a,Num b)=> [a] - > b类型签名绑定的上下文(Ord a,Num b)中推导出(b〜Int)
另外我发现我不能使用200.0,如果我想浮动作为默认值。 编译器说:“无法推论(小数b)由'200.0'引起的”
任何人都可以将一些代码显示为一个函数(不是前奏),它需要一个arg来存储一些变量,以便我可以在其他函数中使用它? 我可以在main = do中做到这一点,但希望使用优雅的功能来实现这一点。 Hasekll有什么全球性的东西吗? 我google了一下,但似乎没有。
我想用Haskell来替换我的一些python脚本,尽管它不容易。
我认为这种类型签名并不完全代表你的想法:
setOffsetTime :: (Ord a, Num b)=>[a] -> b
,说什么“如果你给我类型的值[a]
任何类型的a
选择那就是成员Ord
类型的类,我会给你类型的值b
,对于任何类型b
您选择那是Num
类型的成员“。 调用者可以选择每次调用setOffsetTime
使用的特定类型a
和b
。
所以试图返回Int
(或Float
,或任何特定类型)的值是没有意义的。 Int
的确是类型类的成员Num
,但它不是那种类的任何成员Num
。 根据这种类型的签名,我应该能够创建一个您从未见过的Num
全新实例,从您的模块中导入setOffsetTime
,并将其命名为获取我的新类型的值。
为了得到可接受的返回值,您只能使用同样返回任意Num
函数。 你不能使用任何特定具体类型的函数。
存在类型本质上是一种允许被调用者为类型变量选择值的机制(然后调用者必须被写入工作而不管该类型是什么),但这并不是你想要在你还在学习。
如果你确信你的函数的实现是正确的,即它应该将输入列表中的第一个元素解释为要返回的数字,并返回200
如果没有这样的参数,那么你只需要确保类型签名匹配该实现(现在它不这样做)。
为此,例如,您可以删除类型签名并要求ghci推断该类型:
$ ghci
GHCi, version 7.6.2: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :{
Prelude| let setOffsetTime [] = 200
Prelude| setOffsetTime (x : xs) = read x :: Int
Prelude| :}
Prelude> :t setOffsetTime
setOffsetTime :: [String] -> Int
Prelude> :q
Leaving GHCi.
$
事实上,
setOffsetTime :: [String] -> Int
setOffsetTime [] = 200
setOffsetTime (x : xs) = read x :: Int
编译好。
如果你想要一个更通用的类型,你可以从第二种情况下删除ascription :: Int
。 上面的方法然后告诉你,你可以写
setOffsetTime :: (Num a, Read a) => [String] -> a
setOffsetTime [] = 200
setOffsetTime (x : xs) = read x
从你添加到你的问题的评论中,我明白你想让你的函数返回一个浮点数。 在这种情况下,你可以写
setOffsetTime :: [String] -> Float
setOffsetTime [] = 200.0
setOffsetTime (x : xs) = read x
或者更一般的:
setOffsetTime :: (Fractional a, Read a) => [String] -> a
setOffsetTime [] = 200.0
setOffsetTime (x : xs) = read x
链接地址: http://www.djcxy.com/p/43127.html