2017-12-16 12 views
4

私はちょうどHaskellの学習を始めました。私は関数を反復しようとします\x->[x]。私は、これは動作しません反復の間に型の変更があっても正式な定義が同じである関数を "反復"する方法

foldr1 (.) (replicate 2 (\x->[x])) $ (8 :: Int) 

によって結果[[8]]を得ることを期待し、次のエラーメッセージが得られます。

がチェックに発生します:a ~ [a]

期待タイプ:無限の種類を構築することはできませんが。 [a -> a]

実際の型:[a -> [a]]

なぜ動作しないのか分かります。それは、そのfoldr1が署名foldr1 :: Foldable t => (a -> a -> a) -> a -> t a -> aを入力しているためであり、その最初のパラメータの型シグネチャではなく、a -> a -> b

どちらとしてa -> a -> aとるんこれは、同じ理由:しかし

((!! 2) $ iterate (\x->[x]) .) id) (8 :: Int) 

、これは動作します:

(\x->[x]) $ (\x->[x]) $ (8 :: Int) 

及びIは、(\x->[x])第一及び第二の一つは、異なるタイプ(すなわち[Int]->[[Int]]Int->[Int])であることを理解し、形式的には同じように見えます。

は今、このようなリストを構築する方法があり、100

私の質問はであると言う、私は大規模な数に2を変更する必要があると言いますか?私はTemplate Haskellのようなメタプログラミング技術に頼らなければなりませんか?メタプログラミングに頼らなければならないのですが、どうすればいいのですか?

サイドノードとして、このようなリストの文字列表現を構築しようとしましたが、readです。文字列は構築がはるかに簡単ですが、私はどのようにreadそのような文字列を知りません。例えば、

read "[[[[[8]]]]]" :: ?? 

私は、ネストされた層の数はアプリオリを知られていないとき??部分を構築する方法がわかりません。私が考えることができる唯一の方法は、メタプログラミングに頼っていることです。

上記の質問は十分に面白くないかもしれません。私は「実生活」の場合があります。次の関数を考えてみましょう:

natSucc x = [Left x,Right [x]] 

これはformal definition of natural numbersで使用succ機能です。再び、私は単にfoldr1-replicateまたは!!-iterateそれをすることはできません。

ご協力いただければ幸いです。コードスタイルに関する提案も歓迎します。

編集: (もう一度、あなたの時間と努力をありがとうございました)これまでの3つの答えを見た後、私は、これはリストに限定されるものではなく、より一般的な問題です実現。妥当な型のファンクタごとに同様のタイプの問題を作成することができます(それは自分自身ではあまり意味がないかもしれませんが、Just Just Just 8を取得したい場合はどうすればよいでしょうか?)。

+1

反復回数nが静的にわかっている場合、naturalsのシングルトンを利用する可能性がある型ファミリ( 'Apply n [] a')を使って何かを行うことができます。それ以外の場合は、リストの入れ子を示す十分な大きさの合計型を作成することができます。 'データ値a = V a | L [Value a] '(これはバラの木です。 – chi

+0

ありがとうございます。私はこれらのオプションをチェックします。 –

+0

これをリストとして作成することはできません。だから、その場合は、再帰的なデータ型を定義する必要があります(ツリーのように、inodeに値を置かない)。 Haskellでは依存型の –

答えて

関連する問題