1

我有下面的代码来获取参数来设置一些偏移时间。

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)

此外,我发现如果我希望 float 作为默认值,我无法使用 200.0。编译器说“无法从文字 '200.0' 推导出(小数 b)”

任何人都可以向我展示一些代码作为函数(不是在前奏中),它需要一个 arg 来存储一些变量,以便我可以在其他函数中使用?我可以在 main = do 中做到这一点,但希望使用一个优雅的函数来实现这一点。Hasekll 中是否有任何全局常量?我google了一下,好像没有。

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

4

2 回答 2

6

我认为这种类型签名并不完全意味着您认为它的作用:

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

意思是“如果你给我一个 type 的值,对于[a]选择的任何类型的成员,我会给你一个 type 的值,对于选择的任何类型的成员班级”。调用者可以选择每次调用时使用的特定类型。a OrdbbNumabsetOffsetTime

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

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

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

于 2013-04-18T04:08:54.003 回答
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
于 2013-04-18T02:48:48.580 回答