1

我正试图围绕 Haskell 的语法。

这个问题在逻辑上很容易解决。我必须分解正整数和负整数的列表并将它们分组,以便

[1,2,3,-1,-2,-3,1,2,3] 变为 [[1,2,3],[-1,-2,-3], [1,2,3] ]

我想使用一个更高阶的函数 foldr ,以便能够通过一个接受两个争论的匿名函数来做到这一点。

这就是我到目前为止所拥有的。

split = foldr (\ x y -> if (x > 0) 
                        then if (head (head y)) < 0
                            then [x] : y
                            else x : head y --error here
                        else if (x < 0) 
                        then if (head (head y)) > 0
                            then [x] : y
                            else x : head y
                        else y
                )
                [[]]

这是我得到的错误

 Occurs check: cannot construct the infinite type: a0 = [a0]
    In the first argument of `(:)', namely `x'
    In the expression: x : head y
    In the expression:
      if (head (head y)) < 0 then [x] : y else x : head y

我有两个问题。

1) 为什么在第 7 行出现类型错误?

我不是将整数 (x) 连接到整数列表 (head y)

2)你如何使用守卫写出条件?我试过这样做,但我一直在parsing error at '|'

4

2 回答 2

2
  1. 一个函数只能有一个具体的返回类型,并且[x] : y是不同于x : head y.

  2. takeWhile用and编写它可能更容易dropWhile

    split l = split' (if head l > 0 then (>) else (<)) l 
      where split' op [] = []
            split' op l = takeWhile (`op` 0) l : split (dropWhile (`op` 0) l)
    
于 2012-10-14T15:48:52.790 回答
1

你只是缺少保持tail y。在

foldr (\ x y -> if (x > 0) 
                    then if (head (head y)) < 0
                        then [x] : y
                        else x : head y

你有x :: (Num a, Ord a) => a,y :: (Num a, Ord a) => [[a]]head y :: (Num a, Ord a) => [a].

所以忘记tail y剃掉一层[]else分支应该是

else (x:head y) : tail y

在外部的两个分支中if

但是,你的函数在那之后有两个语义问题。

首先,您不处理head y空的情况,当到达列表末尾时会导致异常,其次,它不适用于无限列表,因为组合函数不构造任何在它的第二个参数已知之前的结果。如果后者是一个问题,你可以在这个答案中找到一个足够惰性的组合函数。

于 2012-10-14T15:24:31.910 回答