Int和Num类型的haskell

时间:2013-04-18 01:54:18

标签: function variables haskell types

我在下面的代码中使用args来设置一些偏移时间。

setOffsetTime :: (Ord a, Num b)=>[a] -> b
setOffsetTime [] = 200
setOffsetTime (x:xs) = read x::Int

但是编译器说“无法从上下文(Ord a,Num b)中推断出(b~Int)由setOffsetTime ::(Ord a,Num b)=> [a]的类型签名约束 - > b

此外,如果我想将float作为默认值,我发现无法使用200.0。编译器说“无法推断出(小数b)来自文字”200.0“

任何人都可以向我展示一些代码作为一个函数(不在前奏中),它使用arg存储一些变量,以便我可以在其他函数中使用吗?我可以在main = do中做到这一点,但希望 使用优雅的功能来实现这一目标。 Hasekll有没有全球不变的东西?我用Google搜索,但似乎没有。

我想用Haskell替换我的一些python脚本,虽然这并不容易。

2 个答案:

答案 0 :(得分:6)

我认为这种类型的签名并不代表你的想法:

setOffsetTime :: (Ord a, Num b)=>[a] -> b

说的是“如果您为我提供[a]类型的值,则对于任何类型a 选择Ord的成员类型类,我将为您提供类型为b的值,适用于选择b类型类的成员“的任何类型Num调用者可以选择每次调用a时使用的特定类型bsetOffsetTime

因此,尝试返回类型Int(或Float或任何特定类型)的值没有意义。 Int确实是类Num的成员,但它不是类型类Num的任何成员。根据该类型签名,我应该能够创建一个你以前从未见过的Num全新实例,从模块中导入setOffsetTime,并调用它来获取我的新值类型。

要想出一个可接受的返回值,你只能 使用同样返回任意Num的函数。您不能使用特定具体类型的任何函数。

存在类型本质上是一种机制,允许被调用者为类型变量选择值(然后调用者必须被写入工作而不管该类型是什么),但这并不是你想要得到的东西在你还在学习的时候。

答案 1 :(得分:4)

如果您确信函数的实现是正确的,即它应该将其输入列表中的第一个元素解释为要返回的数字,如果没有这样的参数则返回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

编译好。

如果您想要稍微更通用的类型,可以从第二种情况中删除归属:: 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