2006-06-30 [長年日記]
λ. となりの801ちゃん
なんか、「となりの801ちゃん」というブログを紹介されたのだが、これ凄いね。
λ. concatN
<URL:http://d.hatena.ne.jp/lethevert/20060630/p3> より。
ぁゃιぃ拡張機能を使うと出来ないこともない気がする。以下のコードの元ネタはOlegさんの Deepest functor 。なお、私はどうしてこれでうまくいくのかいまだに良くわかってない。
{-# OPTIONS -fglasgow-exts #-} {-# OPTIONS -fallow-undecidable-instances #-} {-# OPTIONS -fallow-overlapping-instances #-} module ConcatN where data Atom -- Check if a type is a collection type. This is the only typeclass that -- needs overlapping instances class IsCollection t coll | t -> coll instance IsCollection (m a) (m ()) instance TypeCast Atom coll => IsCollection t coll -- our common working horse class TypeCast a b | a -> b, b->a where typeCast :: a -> b class TypeCast' t a b | t a -> b, t b -> a where typeCast' :: t->a->b class TypeCast'' t a b | t a -> b, t b -> a where typeCast'' :: t->a->b instance TypeCast' () a b => TypeCast a b where typeCast x = typeCast' () x instance TypeCast'' t a b => TypeCast' t a b where typeCast' = typeCast'' instance TypeCast'' () a a where typeCast'' _ x = x class ConcatN a c | c -> a where concatN :: c -> [a] instance (IsCollection c coll, ConcatN' coll a c) => ConcatN a c where concatN = concatN' (undefined::coll) class ConcatN' coll a c | coll c -> a where concatN' :: coll -> c -> [a] instance ConcatN' Atom a a where concatN' _ a = [a] instance (ConcatN a c) => ConcatN' [()] a [c] where concatN' _ = concatMap concatN test1 = concatN [[[True]],[[False,True]],[]] test2 = concatN [[1::Int,2,3],[4]]
深さを指定してconcat
稲葉さんのとこで色々なコードが紹介されていたので、私も少しバリエーションを。深さを指定してconcatするなら、私ならこんな感じで書くかな。
data Z = Z data S n = S n class ConcatN a n l | a n -> l where concatN :: n -> l -> [a] instance ConcatN a Z [a] where concatN _ = id instance ConcatN a n l => ConcatN a (S n) [l] where concatN _ = concatMap (concatN (undefined :: n))
さらに、型クラスではなくGADTを使ったバージョン。
data N a l where Z :: N a [a] S :: N a l -> N a [l] concatN :: N a l -> l -> [a] concatN Z = id concatN (S n) = concatMap (concatN n)
凄いとは思いますが、身近な友達がどっぷりと801ちゃんなので何も言えない……
わぁ。。。。なんかすごく素敵な世界<br>どっぷりつかりたい。
>yuragiさん<br>あらら。<br>私も何も言えないっちゃ何も言えないんですが、801ちゃんな人には感心しきりですよ。<br><br>>かずと<br>お〜い。<br>帰ってこれなくなっても知らないよ〜。