2012-02-22 5 views
15

我々はHaskellで異質なリストを作成する対の配列を使用することができます。ハスケル:タイプ別に不均一なリストをフィルタリング

type a *: b = (a, b) 
a *: b = (a, b) 
infixr 5 *: 

hlist :: Int *: String *: Maybe Float *:() 
hlist = 1 *: "hello" *: Just 3 *:() -- (1, ("hello", (Just 3,()))) 

は、我々はこれらのリストにはタイプレベルのフィルタリングを行うことができます方法はありますか?これは、別個のタイプab、およびcのためにいくつかの多型の機能そのhfilterように定義されています

hfilter :: a *: b *: c *: a *: b *: a *:() -> a *: a *: a *:() 
hfilter :: a *: b *: c *: a *: b *: a *:() -> b *: b *:() 
hfilter :: a *: b *: c *: a *: b *: a *:() -> c *:() 
hfilter :: a *: b *: c *: a *: b *: a *:() -> () 

答えて

16

それはさておきとして(数タイプの拡張子を持つことが可能です、質問を投稿するとき、あなたの例のコードがコンパイルされることを確認してください。私はかなりの修正を加えなければならなかった)。

これで、必要なリストのタイプを明示的に定義することで、アイテムをタイプ別にフィルタリングできます。

*Main> hfilter hlist :: [Int] 
[1,2] 
*Main> hfilter hlist :: [String] 
["hello"] 
*Main> hfilter hlist :: [Maybe Float] 
[Just 3.0] 
*Main> hfilter hlist :: [Maybe Int] 
[] 

それは異質なリストの種類と我々はによってフィルタリングする型を取るマルチパラメータ型クラスTypeFilterを定義することによって動作します。私たちは、その後、空のリスト/ユニット()と型が一致する(TypeFilter (t :* rest) t)、最終的にヘッドの種類は、我々は(TypeFilter (a :* rest) t)を取得するタイプと異なるリストのためのリストのためのためのインスタンスを定義します。

注意それは最後のインスタンスでatは、異なるタイプでなければならないことを意味する方法はありませんが、彼らはより具体的なとしてインスタンスTypeFilter (t :* rest) t同じOverlappingInstancesカウントされ、TypeFilter (a :* rest) t 1の上に、それを選択したとき。

+0

コンパイルの問題で申し訳ありませんが、私は携帯電話から投稿していました。 – rampion

+1

これで、フィルター引数を渡して 'OverlappingInstances'を必要としないバージョン(https://gist.github.com/1885439)' hfilter :: a - > h - > h''、それは出力に異種リストを使用します。 hfilter(undefined :: Int)hlist ::() 'は'() '、' hfilter(未定義:: Int)hlist :: Int:*() 'は' 1:*() 'と' hfilter( undefined :: Int)hlist :: Int:* Int:*() 'は' 1:* 2:*() 'です。 – rampion

+0

argですが、実際には 'OverlappingInstances'が必要です。 – rampion

2

存在するがあなたが聞いたことをする方法、ここでハスケルの強さを演じていない可能性が非常に高いです。あなたのニーズは?通常、代数データ型で必要となるすべてのバリアントを列挙できます。あなたのリストは均質になり、要素を操作してパターンマッチングを行うことができます。

+0

ADTを使うと、おそらく '' catMaybes'(http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Maybe)と同様の精神で解決することになります。 html#v:catMaybes)、特定のコンストラクタでリストをフィルタリングします。 –

+0

私は、スタックベースのDSL(やや類似した要素)をhaskellに書いています。この場合の異種リストはスタックです。 – rampion

+1

ああ、SamiのSNOC-pairベースのポリモーフィックスタックの精神に似ていると思います(https://github.com/leonidas/codeblog/blob/master/2012/2012-02-17- concatenative-haskell.md)? –

関連する問題