1. ホーム
  2. haskell

[解決済み] Haskellで "length "関数を使用しない場合のリストの長さ

2022-02-08 21:55:55

質問

リストの長さを確認したいのですが、関数を使用せずに length . このプログラムを書いたのですが、うまくいきません。なぜか教えてください。ありがとうございます。

let y = 0
main = do
  list (x:xs) = list (xs)
  y++

list :: [Integer] -> Integer
list [] = y

解決方法は?

あなたのプログラムは、かなり " に見えます。 必須 という変数を定義しています。 y を記述し、その後、何らかの方法で do を呼び出す(?)。 list を自動的に返すような関数(? y をインクリメントしたい。 y .

Haskell(そしてほとんどの関数型、宣言型)言語はそういうわけにはいきません。

  • 宣言型言語では、以下のように 変数 は一度だけで、値が設定された後は、通常、その値を変更する方法はありません。
  • Haskellでは do は通常モナドに使用されるのに対し length 純粋 関数を使用します。
  • その let は、式のスコープ内で変数を定義するための構文です。
  • ...

Haskell(あるいは他の関数型言語)をプログラミングするためには、quot;think functional"が必要です。 数学的 を使用する方法 関数のみ .

数学で言えば、空リスト [] は明らかに長さが 0 . さらに、リストが空でない場合、最初の要素("head")と残りの要素("tail")が存在することになります。この場合、結果は1+末尾の長さになります。これを数式で表すと、次のようになる。

さて、この関数を次のようなHaskellのコードに簡単に変換することができる。

ownLength :: [a] -> Int
ownLength [] = 0
ownLength (_:xs) = 1 + ownLength xs

さて、Haskellでは、通常、次のようなものも使用します。 アキュムレータ を実行するために 末尾再帰 : 再帰呼び出しの際にパラメータを渡し、その都度 更新 という変数があります。再帰が終了したら、後処理をしてアキュムレータを返すこともある。

この場合、アキュムレータはこれまでに見た長さになるので、次のように書くことができる。

ownLength :: [a] -> Int
ownLength = ownLength' 0
    where ownLength' a [] = a
          ownLength' a (_:xs) = ownLength' (a+1) xs