1

私は haskell が初めてで、いくつかの演習を試しています

エラーが生成された理由と生成された理由がわかりません

split = foldr 
        (\x y -> y:x)
        [[]]

インタプリタのエラーは次のとおりです

    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the first argument of `(:)', namely `y'
    In the expression: y : x
    In the first argument of `foldr', namely `(\ x y -> y : x)'
Failed, modules loaded: none.

誰でも助けることができますか?前もって感謝します

4

3 に答える 3

6

フォルダーの種類は

foldr :: (a -> b -> b) -> b -> [a] -> b

分割して

split = foldr (\x y -> y:x) [[]]

yまたy:x、同じタイプである必要があります。これは、どのタイプでも不可能でありxyリストy:xの中で常に1ステップ深くなりyます。

やりたかったと思いますx:yか?

于 2012-10-10T15:21:04.680 に答える
2

foldr:の型を思い出してください(a -> b -> b) -> b -> [a] -> b。これはfoldr、リストの要素を最終的な結果の型の値と組み合わせて、結果の型の新しい値を生成する関数を期待していることを示しています。

最初の引数にはfoldr、 functionを指定しました\x y -> y:x。ここでx、 はリスト要素でありy、次のステップの結果は右側にあります。このラムダを適用した結果は、 と同じ型になるはずyです。

しかし、 の型(:)a -> [a] -> [a]-- つまり、リストの先頭に 1 つの要素を追加します。式y:xでは、「結果」タイプの何かを取得し、それを結果として使用されるリストの要素として使用しています。

そのため、GHC は結果の型が typebと同じであると推論しようとし[b]、それはもちろん type と同じ[[b]]であり、[[[b]]]... などです。したがって、「無限型」について文句を言います。

于 2012-10-10T15:25:08.603 に答える
1

私の前の投稿はあなたの質問に答えますが、コメントの後、述語でリストを分割する関数が必要であることがわかります。

GHC.Exts モジュールから groupWith::Ord b => (a -> b) -> [a] -> [[a]] を使用して、(a -> Bool) 型の関数を例:

groupWith even [1,2,3,4,5,6] yields [[1,3,5],[2,4,6]]

また、醜いものですが、あなたが望むタイプの「外出」を実現するものは次のとおりです。

split::Eq a => (a -> Bool) -> [a] -> [[a]]
split f ls = (ls \\ rl):rl:[]
    where rl = filter f ls

ただし、これは、指定したバイナリ関数のために、指定されたリストを常に 2 つのリストに分割します。

于 2012-10-10T16:05:51.947 に答える