小编Vla*_*sky的帖子

为什么在Haskell中写类型声明?

我是Haskell的新手,我试图理解为什么需要编写类型声明.由于Haskell有类型推断,我什么时候需要第一行?GHCI似乎生成正确的输出我用':t'

到目前为止,我发现的唯一一个似乎需要声明的例子如下.

maximum' :: (Ord a) => [a] -> a  
maximum' = foldr1 max
Run Code Online (Sandbox Code Playgroud)

但是,如果我添加"-XNoMonomorphismRestriction",则不再需要标志声明.是否存在类型推断不起作用且需要指定类型的特定情况?

由于我可能在类型声明中有错误并且没有直接的好处,我宁愿不写它.我刚刚开始学习Haskell,所以如果我错了请纠正我,因为我想养成良好的习惯.

编辑:事实证明,类型推断是真实世界Haskell书中的一个双刃剑部分,对这个主题进行了很好的讨论.

haskell types type-inference

24
推荐指数
3
解决办法
1914
查看次数

Haskell函数中的自引用

我正在学习Haskell,而Haskell Wiki上的以下表达式 让我很困惑:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么会这样.

如果我应用标准Currying逻辑,则(zipWith (+))返回一个函数将list作为参数,然后返回另一个函数,该函数将另一个列表作为参数,并返回一个list(zipWith::(a -> b -> c) -> [a] -> [b] -> [c]).因此,fibs是对列表的引用(尚未评估),并且(tail fibs)是相同(未评估)列表的尾部.当我们尝试evaluate(take 10 fibs)时,前两个元素绑定到01.换句话说fibs==[0,1,?,?...](tail fibs)==[1,?,?,?].第一次添加完成后fibs变为[0,1,0+1,?,..].同样,在第二次添加之后我们得到了[0,1,0+1,1+(0+1),?,?..]

  • 我的逻辑是否正确?
  • 有没有更简单的方法来解释这个?(知道Haskell编译器对此代码做什么的人的任何见解?)(欢迎链接和参考)
  • 确实,这种类型的代码只能用于懒惰的评估吗?
  • 我做什么评价fibs !! 4
  • 此代码是否假设zipWith首先处理元素?(我认为不应该,但我不明白为什么不)

编辑2:我刚刚发现上述问题并在此处得到很好的解答.如果我浪费了任何人的时间,我很抱歉.

编辑:这是一个更难理解的案例(来源:Project Euler论坛):

filterAbort :: (a -> …
Run Code Online (Sandbox Code Playgroud)

recursion haskell lazy-evaluation self-reference

8
推荐指数
1
解决办法
1180
查看次数

haskell列表理解表现

以下是蛮力毕达哥拉斯三胞胎问题的三个版本,附加约束为a + b + c = 1000.所有这些都符合-O3与GHC 7.0.3.下面列出了样本运行时间.

问题:

  1. 为什么第二个版本比第一个版本运行得更快?
  2. 为什么第三个版本比第二个版本运行得更快?

我意识到差异很小,但排序平均一致.

main=print . product . head $ [[a,b,c] | a<-[1..1000],b<-[a..1000], let c=1000-a-b, a^2+b^2==c^2]
real    0m0.046s
user    0m0.039s
sys     0m0.005s

main=print . product . head $ [[a,b,c] | a<-[1..1000],b<-[1..1000], let c=1000-a-b, a^2+b^2==c^2]
real    0m0.045s
user    0m0.036s
sys     0m0.006s

main=print . product . head $ [[a,b,c] | a<-[1..1000],b<-[1..1000], b>=a, let c=1000-a-b, a^2+b^2==c^2]
real    0m0.040s
user    0m0.033s
sys     0m0.005s
Run Code Online (Sandbox Code Playgroud)

performance haskell list-comprehension

7
推荐指数
1
解决办法
1029
查看次数

模式与守卫:否则不匹配?

给定空字符串时,以下两个函数的行为有所不同:

guardMatch l@(x:xs) 
    | x == '-'        = "negative " ++ xs
    | otherwise       = l

patternMatch ('-':xs) = "negative " ++ xs
patternMatch l        = l
Run Code Online (Sandbox Code Playgroud)

这是我的输出:

*Main> guardMatch ""
"*** Exception: matching.hs:(1,1)-(3,20): Non-exhaustive patterns in function guardMatch

*Main> patternMatch ""
""
Run Code Online (Sandbox Code Playgroud)

问题:为什么'否则'关闭空接字符串?

haskell pattern-matching guard-clause

4
推荐指数
2
解决办法
2467
查看次数

如何在Haskell中实现'show'?

我试图了解类型系统在Haskell中的工作原理.

class (Show a) => MyShow a where 
    myShow :: a -> String

instance MyShow Integer where 
    myShow = show 

myshow :: (Show a) => a -> String
myshow = show

main  = do 
    putStrLn $ myshow 1
    putStrLn $ myShow (2 :: Integer) -- why do I need '::Integer' here?
Run Code Online (Sandbox Code Playgroud)

为什么'myshow 1'在没有类型的情况下工作,而'myShow 2'在没有显式类型的情况下导致错误:

Ambiguous type variable `a0' in the constraints:
  (MyShow a0) arising from a use of `myShow'
              at nooverinst.hs:12:16-21
  (Num a0) arising from the literal `2' at nooverinst.hs:12:23 …
Run Code Online (Sandbox Code Playgroud)

haskell show typeclass

2
推荐指数
1
解决办法
384
查看次数