我正在尝试编译一个非常简单的haskell 程序。要么我不知道如何在 Haskell 中对语句(表达式)进行排序,要么没有办法做到这一点。
我本质上想要一个以下形式的函数:
f = <do stuff 1>
<do stuff 2>
...
以下内容应该模拟以下模式
<do stuff>
<tail recursion>
但编译失败:
go 0 = 0
go i = case i of
1 -> 2
_ -> 3
go (i-1)
这也不起作用(更简单,没有递归):
go i = 1
2
上面的代码可以编译,但是在运行时我得到了神秘的信息:
No instance for (Num (a0 -> t0))
arising from a use of `go'
Possible fix: add an instance declaration for (Num (a0 -> t0))
In the expression: go 2
In an equation for `it': it = go 2
我的缩进有问题吗?排序不正确的问题?或者说没有测序能力?如果不排序,你会直接做什么
<do stuff>
<tail recursion>
?
<小时/>感谢您的回复。
很难相信 Haskell 中的函数基本上仅限于一个“表达式”或“语句”或任何你想调用它的东西。您将如何解决以下人为的玩具示例(用 erlang 编写,但可以轻松地直接翻译成 prolog 或整个其他语言):
count([], X) -> X;
count([_|B], X) ->
Y = X+1,
count(B, Y).
运行示例:
erlang> count([a,b,c,d,e],0).
5
第二个子句符合我之前描述的模式:
<do stuff>
<tail recursion>
我想这个特定的例子映射到了这里描述的Haskell“让……进来”。但如果需要 10 个、20 个或更多“做事”怎么办?并且这个“let...in”保证是尾递归的(上面的例子保证在erlang、prolog、scheme等中)。
有没有一种方法可以简单地将一堆语句或表达式“串在一起”或“排序”?在 prolog 或 erlang 中,排序是通过逗号完成的(参见上面的玩具示例)。在c/c++中,它是通过分号完成的。我认为 Haskell 运算符只是空白,但也许它只是没有用这种语言完成?
最佳答案
在 Haskell 中,你不会编写“做事”的函数。您编写计算值的函数。有鉴于此,按照您建议的方式构建函数是没有意义的:
f = <do stuff 1>
<do stuff 2>
相反,您可以编写一个实际的数学函数,它是一个依赖于某些输入的单个表达式:
f x y = blah x blah y blah
将其分解为子表达式可能会很方便
f x y = res1 + res2
where res1 = x * 3
res2 = y + 4
但最终,它只是一个单一的表达式。
<小时/>以 do
表示法编写的 Monadic 代码看起来可以按顺序“做事”:
f = do
thing1
thing2
但这只是一个幻觉。它也脱糖为单个表达式:
f = thing1 >> thing2
该表达式指出,f
是一个由 thing1
和 thing2
组合而成的值。现在,IO 代码可能编译为按顺序“做事”的代码,但这不是 Haskell 中的含义。人们不只是在 Haskell 中“做事”。相反,您撰写。
关于haskell - Haskell 中的语句排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9954968/