15

私はHaskellに興味のある初心者で、フラットマップ(>> =)を自分で実装して理解を深めようとしています。現在私は持っています

flatmap :: (t -> a) -> [t] -> [a]  
flatmap _ [] = []  
flatmap f (x:xs) = f x : flatmap f xs  

これは「マップ」部分を実装しますが、「フラット」は実装しません。
私が行った変更のほとんどは、がっかりし、かなり情報がないという結果になります

Occurs check: cannot construct the infinite type: a = [a]  
    When generalising the type(s) for `flatmap' 

エラー。

私は何が欠けていますか?

4

1 に答える 1

24

このようなエラーは、指定した型シグネチャが関数の実際の型と一致しない場合に発生します。エラーの原因となるコードを表示しなかったので、推測する必要がありますが、次のように変更したと思います。

flatmap _ [] = []  
flatmap f (x:xs) = f x ++ flatmap f xs

それが起こったとき、それは完全に正しいです。ただし、型アノテーションも変更するのを忘れた場合は、次のようになります。

タイプチェッカーは、との結果に++を使用していることを確認しf xますflatmap f xs。同じタイプの2つのリストで機能するため++、タイプチェッカーは、両方の式が同じタイプのリストに評価される必要があることを認識します。flatmap f xsこれで、タイプチェッカーはそれがタイプの結果を返すことも知っている[a]ので、タイプf xも持っている必要があり[a]ます。ただし、型アノテーションでは、fは型を持っていると書かれているt -> aので、型f xを持っている必要がありaます。これにより、タイプチェッカーは矛盾していると結論付け[a] = a、表示されるエラーメッセージにつながります。

型署名をに変更flatmap :: (t -> [a]) -> [t] -> [a](または削除)すると、機能します。

于 2010-06-07T02:44:32.780 に答える