haskell - Haskell 中的语句排序?

标签 haskell

我正在尝试编译一个非常简单的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 运算符只是空白,但也许它只是没有用这种语言完成?

最佳答案

Obligatory meme

在 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 是一个由 thing1thing2 组合而成的值。现在,IO 代码可能编译为按顺序“做事”的代码,但这不是 Haskell 中的含义。人们不只是在 Haskell 中“做事”。相反,您撰写

关于haskell - Haskell 中的语句排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9954968/

相关文章:

haskell - git commit 的本地依赖

string - 在 Haskell 中比较两个字符串

haskell - 在 Haskell 中,为什么我需要在实例声明中指定类型类?

haskell - 将 setter/getter 组合成折叠

haskell - 由于标志字节串--lt-0_10_4,无法使用 Stack 构建 hello world 程序

haskell - 为什么 Conduit 和 Pipe 不能有 Arrow 实例?

haskell - 为什么不能将 Int 与 Nums 或 Ords 进行比较?

arrays - Repa 阵列上的并行 mapM

performance - 如何处理具有恒定内存的两条长线?

design-patterns - 静态类型检查的设计模式