Haskell https://en.m.wikipedia.org/wiki/L-systemでL システムを表現しようとしています。具体的には、藻類の成長をモデル化するための Lindenmayer のオリジナルの L システムです。
変数 : AB
定数 : なし
公理 : A
規則 : (A → AB), (B → A)
私にとって、この問題に取り組む自然な方法は、リスト内の各要素にルールを適用することです。これは、(私にとって) ある種の文字列置換を使用して解決策をモデル化できることを意味します。
例:
「文字」のリスト [A, B, A] については、ルールを適用して [A → AB, B → A, A → AB] = [A, B, A, A, B] を取得します (このモデルではHaskell とうまく連携するには、AB をリスト [A, B] と見なす必要があります。これは、上記のルールで生成された他の結果と結合します)。
以下に含まれるコードを作成しました。これは、A または B 以外の文字を処理する必要のないデータ コンストラクターを備えています。
data Letter = A | B deriving (Show, Eq)
type Alphabet = [Letter]
algae :: Alphabet -> Alphabet
algae = concat . map (\c -> if
| c == A -> A:[B]
| c == B -> [A])
上記のコードは、それ自体を引数として呼び出すと、期待される結果が得られるようなものです。それ
algae $ algae $algae [A] = [A, B, A, A, B]
繰り返されるアプリケーションは期待どおりに機能します。
次に達成したいことは、関数がそれ自体に再帰的に適用されることですが、これを表現できていません。これは、藻類を無限に何度も自分自身に適用することによって受け取る無限リストを生成する関数を asalgae [A]
または just algae
(型シグネチャを に変更する必要があります)で呼び出せるようにしたいということです。algae :: Alphabet
私は敗北を認めたので、http://hackage.haskell.org/package/lindenmayer-0.1.0.0/docs/Lindenmayer-D0L.htmlを見ましたが、コードを(まだ)そのままでは理解できず、他のものも見つけました同様に紛らわしい実装。
folds
usingと関数を使用しようと最善を尽くしましfix
たが、失敗しました。また、次のような他の再帰的定義から借りようとしました。
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
しかしzipWith
、二項演算子が必要なため、そのアプローチは失敗します。この問題はモナドなしで解決できますか? もしそうなら、どのように?