2012-02-11 12 views
1

私は非常に直感的だと思うHaskellでメソッドを作成しようとしています。私は任意の深いリストのリストを*持っています。再帰の深さにかかわらず、リスト内の特定のアトムを取り出したいと思います。 Haskellで再帰的リストを実装する方法とそれを操作する方法

type List = [Array] 
data Array = Int | List 

drill :: Array -> [Int] -> Array 
drill xs (index:[]) = xs !! index 
drill xs (index:is) = drill (xs !! index) is 

は、しかし、私はGHCiの中にロードするときに、次の受信:

drill.hs:5:23: 
Couldn't match expected type `[Array]' with actual type `Array' 
In the first argument of `(!!)', namely `xs' 
In the expression: xs !! index 
In an equation for `drill': drill xs (index : []) = xs !! index 

私が書いたことは私には直感的なようだが、はっきりとHaskellはタイプの問題を持っているここに私の努力です。そして、ハスケル初心者のように、私は型エラーを解釈する上で最善ではありません。関数の戻り値の型は、アトム:Int、またはリスト:[Int]のいずれかになります。誰かがこれを解読し、解決策を提案するのを助けることができますか?あなたは

data Array = Int | List 

を言うとき

+3

これはリストではない、それは木です! –

答えて

16

これは "どのIntArrayあり、そして任意のListArrayある" という意味ではありません。代わりに、Arrayには2つのコンストラクタ、IntListがあり、両方とも引数をとらないことを意味します。混乱は、型と同じ名前を持つという事実から生じる。名前を共有する以外のタイプには関係しません。それはあなたの宣言はその代わりに、私たちはそれぞれの代替のための明示的なコンストラクタ名を与える必要があり、基本的

data Array = Foo | Bar 

と同じで、次のとおりです。

type List = [Array] 
data Array = Elem Int | Nest List 

drill :: Array -> [Int] -> Array 
drill xs [] = xs 
drill (Nest xs) (index:is) = drill (xs !! index) is 

これはElemIntを取り、Arrayを返すことを意味し、 NestListで、Arrayを返します。 drill関数を調整して、Nestケースの外にArraysのリストを明示的に取る必要があります。

エラーは基本的にはxsをリストとして使用しようとしていますが、Arrayです。これは、あなたがパターンマッチしなかったからです:あなたの引数(Array)を直接リストとして使用しようとしました。

drillの結果を明示的にパターンマッチングして、それが単一要素かネストされたリストかを判断する必要があることに注意してください。値が文字どおりの型を作る方法はありませんハスケルの整数またはネストされたリストです。ハスケルの組合は、のタグが(つまり、コンストラクタは明示的)であり、サブタイプはありません。

詳細については、this introduction to algebraic data typesLearn You a Haskellからお読みください。

関連する問題