漠然としたタイトルで申し訳ありません。ここにいくつかのコンテキストがあります:http://themonadreader.files.wordpress.com/2013/08/issue221.pdf
前号の GADTs の記事では、Nat 型と、さまざまな型レベルのリスト関数 (concat、!!、head、repeat など) で使用する NatSing 型を紹介しています。これらの関数のいくつかでは、Nat 型で + と < を定義するための型ファミリを作成する必要があります。
data Nat = Zero | Succ Nat
data NatSing (n :: Nat) where
ZeroSing :: NatSing Zero
SuccSing :: NatSing n -> NatSing (Succ n)
data List (n :: Nat) a where
Nil :: List n a
Cons :: a -> List n a -> List (Succ n) a
とにかく、呼び出し元の便宜のために、通常[a]
を に変換する関数「リスト」を作成しました。これには、 (リンクされた記事から)のList n a
ように、入力としてリストの長さが必要です。repeat
list :: [a] -> NatSing n -> List n a
list [] ZeroSing = Nil
list (x:xs) (SuccSing n) = Cons x (list xs n)
list _ _ = error "length mismatch"
ヘルパー関数を利用するとよいtoNatSing :: Int -> NatSing n
ので、上記は次のように記述できます。
list :: [a] -> List n a
list xs = list' xs (toNatSing $ length xs)
where
list' :: [a] -> NatSing n -> List n a
list' = ... -- same as before, but this time I simply "know" the function is no longer partial
そのような関数を書くことは可能toNatSing
ですか? 私は型と格闘してきましたが、まだ何も思いつきません。
どうもありがとう!