Function haskell的Int和Num类型
我有下面的代码来使用args设置一些偏移时间Function haskell的Int和Num类型,function,variables,haskell,types,Function,Variables,Haskell,Types,我有下面的代码来使用args设置一些偏移时间 setOffsetTime :: (Ord a, Num b)=>[a] -> b setOffsetTime [] = 200 setOffsetTime (x:xs) = read x::Int 但编译器说“无法从setOffsetTime的类型签名绑定的上下文(Ord a,Num b)中推断(b~Int):(Ord a,Num b)=>[a]->b 我还发现,如果我想将float作为默认值,我就不能使用200.0。编译器说“不能从
setOffsetTime :: (Ord a, Num b)=>[a] -> b
setOffsetTime [] = 200
setOffsetTime (x:xs) = read x::Int
但编译器说“无法从setOffsetTime的类型签名绑定的上下文(Ord a,Num b)中推断(b~Int):(Ord a,Num b)=>[a]->b
我还发现,如果我想将float作为默认值,我就不能使用200.0。编译器说“不能从文字‘200.0’推导出(分数b)”
有谁能给我看一些代码作为一个函数(不是在前奏曲中),它需要一个参数来存储一些变量,这样我就可以在其他函数中使用了?我可以在main=do中这样做,但希望如此
使用一个优雅的函数来实现这一点。
Hasekll里有什么全局常量的东西吗?我在谷歌上搜索过,但似乎没有
我想用Haskell来替换我的一些python脚本,虽然这并不容易。如果您确信函数的实现是正确的,即它应该将输入列表中的第一个元素解释为要返回的数字,如果没有这样的参数,则返回
200
,那么您只需要确保t类型签名与该实现匹配(目前它没有匹配)
为此,例如,您可以删除类型签名并要求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 :: (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
如果您确信函数的实现是正确的,即它应该将其输入列表中的第一个元素解释为要返回的数字,并且如果没有这样的参数,则返回
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 :: (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
我认为这种类型的签名并不代表你所认为的那样:
setOffsetTime::(Ord a,Num b)=>[a]->b
它说的是“如果你给我一个[a]
类型的值,对于任何a
类型,你选择它是Ord
类型类的成员,我会给你一个b
类型的值,对于你选择它是Num
类型类的成员的任何b
“。调用方可以选择每次调用setOffsetTime
时使用的特定类型a
和b
因此,尝试返回类型为Int
(或Float
,或任何特定类型)的值是没有意义的Int
确实是type类Num
的成员,但它不是type类Num
的任何成员。根据该类型签名,我应该能够创建一个您从未见过的全新的Num
实例,从您的模块导入setOffsetTime
,并调用它以获取我的新类型的值
要获得可接受的返回值,只能使用同样返回任意Num
的函数。不能使用任何特定具体类型的函数
存在类型本质上是一种机制,允许被调用方选择类型变量的值(然后,无论类型是什么,都必须写入调用方才能工作),但在你还在学习的时候,这并不是你真正想要了解的东西。我认为这种类型的签名并不完全意味着你认为它的作用:
setOffsetTime::(Ord a,Num b)=>[a]->b
它说的是“如果你给我一个[a]
类型的值,对于任何a
类型,你选择它是Ord
类型类的成员,我会给你一个b
类型的值,对于你选择它是Num
类型类的成员的任何b
。调用方可以选择每次调用setOffsetTime
时使用的特定类型a
和b
因此,尝试返回类型为Int
(或Float
,或任何特定类型)的值是没有意义的Int
确实是type类Num
的成员,但它不是type类Num
的任何成员。根据该类型签名,我应该能够创建一个您从未见过的全新的Num
实例,从您的模块导入setOffsetTime
,并调用它以获取我的新类型的值
要获得可接受的返回值,只能使用同样返回任意Num
的函数。不能使用任何特定具体类型的函数
存在类型本质上是一种机制,允许被调用方选择类型变量的值(然后,无论类型是什么,都必须写入调用方才能工作),但这并不是你在学习的时候真正想做的事情。只是一句话:在
setOffsetTime
的第二个等式中,你明确声明read x
的结果应该是Int
。这立即意味着您函数的结果类型是Int
,而不是更一般的b
<