1

したがって、リストの最大の要素を見つけるが、高次関数を使用して実装される Haskell で Largest と呼ばれる関数を作成することを想定しています。

私はHaskellを初めて使用するので、これはうまくいかない私の試みです

largest :: [Int] -> Int
largest [] = 0
largest (head : tail) = if (head > tail) then head
else (largest tail)

高次関数の意味がわかりません。

いくつかの助けをいただければ幸いです。

4

4 に答える 4

4

試行を修正するには:

largest :: [Int] -> Int
largest [] = 0
largest (head : tail) = max head (largest tail)

これは、負でない数に対してのみ機能することに注意してください (空のリストには最大値がないことを決定することでこれを修正できます-プレリュードの のようmaximumに、またはの代わりにminBoundforを使用しますが、これはたとえば for では機能しません)。Int0Integer

ただし、これはまだ高階関数を使用していません。この種の問題に適した関数はfoldl(またはより良いData.List.foldl') またはfoldrですが、楽しみを台無しにしたくありません。

于 2013-03-08T10:43:54.100 に答える
2

高階関数は、引数の 1 つとして 1 つ以上の関数を受け取るか、関数を返します。この場合、上位の引数は比較関数であると仮定します。これにより、最大の簡単な定義が得られます。

largest :: [a] -> (a -> a -> Ordering) -> a
largest (x:xs) cmp = go x xs
    where go largest []     = largest
          go largest (x:xs) = case cmp largest x of
             LT -> go x xs
             _  -> go largest xs

また、プレリュードには、これを行うための という関数がありますmaximummaximum [2,3,4,1] == 4

于 2013-03-08T03:56:54.167 に答える
1

既存の回答を完了するには、

最初に克服しなければならない問題は、コードをコンパイルするか、少なくともエラー メッセージを理解することです。このヒントは、直面している問題と、正しいバージョンを得るために修正する方法についての優れたガイダンスを提供するはずです (高次の機能要件を満たしていなくても、少なくとも機能するものはあるでしょう)。

このために、パターン句(head : tail)の 型シグネチャを見てみましょう。

まず (:) 関数については、

(:) :: a -> [a] -> [a] 

次に、 headtailの次の型を推測します(これらは (:) の引数です)。

  • head は Int 型です。
  • テールは [Int] 型です。

もう一度、(>) の型シグネチャを見てみましょう。

(>) :: Ord a => a -> a -> Bool  

制約クラスを省略した場合、単純にするために、次のようになります。

(>) :: a -> a -> Bool  

または、あなたのコードには、

....
if ( head > tail) ...
....

これは、単純化するために次のように書き直すことができます。

....
if ((>) head tail)) ...
....

これまでの説明をすべて使用して、(>) 関数に提供された型を再構築し、問題を理解できるはずです。

次に、コードを修正して動作させることができます。高次関数を見て、それを正しくする
ことができた後。

一般的な意見として、複雑な問題で立ち往生しているときは、それをより小さな問題に分解してみてください。そして、それぞれの下位の問題について、次の料理の原則を適用してみてください。

機能させる、
正しくする、
速くする。

于 2013-03-08T13:20:50.683 に答える
0
if (head > tail)

まず、角かっこは必要ありません。次に、さらに深刻なのheadは整数ですが、整数tailリストです。これら2つのことを比較することはできません。

largest (head : tail) = if (head > tail) then head
else largest tail

これは正しくインデントされていません。はelse、少なくとも。までインデントする必要がありますifthenelseを同じ行に配置するか、次のようなことを行うことができます

if head > tail
  then head
  else largest tail

(繰り返しますが、実際には角かっこは必要ありませんが、何も害はありません。)

最後に、と呼ばれる事前定義された関数とhead、と呼ばれる関数があるtailため、これらは変数名の最良の選択ではありません。慣用的なHaskellの選択はxand xs(複数形の「x」)です。このように書かれたコードがたくさんあります。それxは物であり、物xsのリストであることを思い出させるのにも役立ちます。

于 2013-03-09T09:54:19.063 に答える