1

Haskell の構文に頭を悩ませようとしています。

この問題は、論理的に解決するのが非常に簡単です。正の整数と負の整数のリストを分割し、それらを次のようにグループ化する必要があります。

[1,2,3,-1,-2,-3,1,2,3] は [[1,2,3],[-1,-2,-3], [1,2,3] になります。 ]

2 つの引数を受け取る無名関数でそれを実行できるようにするには、高階関数 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

2 つの質問があります。

1) 7 行目で型エラーが発生するのはなぜですか?

整数 (x) を整数のリスト (head y) に連結していませんか?

2) ガードを使用して条件をどのように書き出すのですか? 私はそれをやってみましたが、私は得続けましたparsing error at '|'

4

2 に答える 2

2
  1. 関数は具体的な戻り値の型を 1 つだけ持つことができ、 と[x] : yは異なる型ですx : head y

  2. takeWhileand で書く方がおそらく簡単です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) => ay :: (Num a, Ord a) => [[a]]、およびがありますhead y :: (Num a, Ord a) => [a]

tail yそのため、 1 層のシェービングを忘れてしまい[]ます。elseブランチは

else (x:head y) : tail y

外側の両方のブランチでif

しかし、その後、関数には 2 つの意味上の問題があります。

まず、リストの最後に到達したときに例外が発生する空のケースを処理しませhead yん。次に、コンビネーター関数は何も構築しないため、無限リストでは機能しません。 2 番目の引数が判明する前に結果が返されます。後者が問題である場合は、この回答で十分に遅延したコンビネーター関数を見つけることができます。

于 2012-10-14T15:24:31.910 に答える