質問

だから、楽しみのためだけに、私はペアノ番号を使用して、HaskellでCountedListタイプでプレーしてきました そして、スマートコンストラクタはします。

タイプセーフheadtailはちょうど私には本当にクールなようです。

そして、私は私が行う方法を知っているものの限界に達したと思う。

{-# LANGUAGE EmptyDataDecls #-}
module CountedList (
  Zero, Succ, CountedList,
  toList, ofList, 
  empty, cons, uncons, 
  head, tail, 
  fmap, map, foldl, foldr, filter
) where

import qualified List (foldr, foldl, filter)
import Prelude hiding (map, head, foldl, foldr, tail, filter)

data Zero
data Succ n
data CountedList n a = CL [a]

toList :: CountedList n a -> [a]
toList (CL as) = as

ofList :: [a] -> CountedList n a
ofList [] = empty
ofList (a:as) = cons a $ ofList as

empty :: CountedList Zero a
empty = CL []

cons :: a -> CountedList n a -> CountedList (Succ n) a
cons a = CL . (a:) . toList

uncons :: CountedList (Succ n) a -> (a, CountedList n a)
uncons (CL (a:as)) = (a, CL as)

head :: CountedList (Succ n) a -> a
head = fst . uncons

tail :: CountedList (Succ n) a -> CountedList n a
tail = snd . uncons

instance Functor (CountedList n) where
  fmap f = CL . fmap f . toList

map :: (a -> b) -> CountedList n a -> CountedList n b
map = fmap

foldl :: (a -> b -> a) -> a -> CountedList n b -> a
foldl f a = List.foldl f a . toList

foldr :: (a -> b -> b) -> b -> CountedList n a -> b
foldr f b = List.foldr f b . toList

filter :: (a -> Bool) -> CountedList n a -> CountedList m a
filter p = ofList . List.filter p . toList

(任意の転記ミスのため申し訳ありません - 私はもともと私のHaskellのコンパイラは現在ダウンしている/ワットでこれを書いているマシン)。

私がやったのほとんどは、W / O問題コンパイルが、私はofListfilterの問題に遭遇します。私は理由を理解すると思う - 私はofList :: [a] -> CountedList n aを言うとき、私はofList :: forall n . [a] -> CountedList n aを言っている - 作成したリストは、任意の数のタイプのものとすることができるという。私が書きたいのは、擬似型ofList :: exists n . [a] -> CountedList n aのと同等ですが、私は方法がわからない。

私が想像してるように私はofListfilter機能を書いてみましょうだろうか私はこれで何ができるかの限界に達している回避策はありますか?私は私が欠けていることをを実存的なタイプといくつかのトリックがあることを意味しています。

役に立ちましたか?

解決

あなたが書き込むことはできません。

ofList :: [a] -> (exists n. CountedList n a)  -- wrong

しかし、あなたが書くことができます。

withCountedList :: [a] -> (forall n. CountedList n a -> b) -> b

、それにあなたがいる限り、その種類は、リストの長さとは無関係であるとして、ofListの結果で行われているだろうか。

を表す関数を渡します

ところで、あなたはリストの型は型システムではその長さに対応することを不変性を確保することができ、かつスマートコンストラクタに依存していません。

{-# LANGUAGE GADTs #-}

data CountedList n a where
    Empty :: CountedList Zero a
    Cons :: a -> CountedList n a -> CountedList (Succ n) a

他のヒント

あなたはofListを定義したり、彼らは実行時の値を持つ交絡タイプ・レベルでチェックしているので、この方法をfilterすることはできません。具体的には、結果のタイプに、CountedList n a、型nは、コンパイル時に決定されなければなりません。暗黙の欲望がnが最初の引数であるリストの長さに相応すべきであるということです。しかし、それは明らかに、実行時まで知られてすることはできません。

さて、型クラスを定義することが可能に数え言い、その後、(適切なHaskellの拡張子を持つ)、これらのように定義します。

ofList :: [a] -> (forall n. (CountedListable CountedList n) => CountedList n a)

しかし、あなたはそのCountedListableは、カウントを抽出するだろうサポートできるだけの操作ので、このような結果と何も苦労し、持っていると思います。あなたは、ヘッドがheadのすべてのインスタンスのために定義することができませんでしたので、このような値のCountedListableを取得すると言うことができませんでした。

scroll top