2017-01-03 13 views
1

私はhaskellを学び、関数tailsを実装しようとしています。これは私の実装です:haskellでtails関数を実装する

tails' :: [a] -> [[a]] 
tails' [] = [] 
tails' (x:xs) = xs:[[tails' xs]] 

しかし、私は

Couldn't match expected type ‘a’ with actual type ‘[[a]]’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for tails' :: [a] -> [[a]] at.. 

私の実装の何が問題になっているコンパイルエラーに実行し続けますか?

+2

あなたのタイプシグネチャによって、 'tails 'xs'は既にリストのリストでなければなりません。 '[[tails 'xs]]のように角括弧で囲むと、リストのリストが2つの特別なシングルトンリストにラップされます。必要なのは 'tails '(x:xs)= xs:tails' xs'です。 – Alec

+0

@Alec:そうです。できます。しかし、私はまだブラケットを取り除かなければならない理由は分かりません。返された値が型シグネチャにあるものと一致することを確実にすることは、プログラマの仕事ではありませんか?あなたが置いている方法:型シグニチャはリストのリストに変換して扱います。 – Ashwin

答えて

4

tails' (x:xs) = xs:[[tails' xs]] 

を交換してください:

tails' (x:xs) = xs : tails' xs 
+2

括弧は必要ありません。 'xs:tails 'xs'はうまくいきます。 – melpomene

+0

@Leandro Galvan:括弧を削除した理由を説明できますか? – Ashwin

+0

@Ashwin大括弧なしの 'tails 'xs'という用語は、すでにリストのリスト、つまり' [[a]] 'のリストです。関数が再帰的であるために少し混乱しますが、宣言した型を見ると、__tails 'はリストを取り、リストのリストを返します.__ 'xs'はリストなので、' tails''に適用するとリストのリストが得られます。 –

3

別に構文型エラーから、あなたの実装が(スペック)は正しくありません。これと比較してください...

Prelude> let tails [] = [[]] 
Prelude|  tails [email protected](x:xs) = y:(tails xs) 
Prelude| 
Prelude> tails "abc" 
["abc","bc","c",""] 
+2

型エラーです。構文エラーではありません。 – chepner

+0

あなたの実装は仕様通りではありません。あなたの実装と 'Data.List'の間で' null(tails undefined) 'の結果を比較してください。 –

+0

@DanielWagner Data.Listの実装がその入力に対して 'False'を返す方法を見ていますが、なぜ' tails undefined = undefined:tails(tail undefined) 'という有用なプロパティですか? – amalloy

関連する問題