3

3つ以上の変数で2つの変数の関数を呼び出すための最良の方法は何ですか?

たとえば、関数が与えられたmax

Prelude> :t max
max :: Ord a => a -> a -> a

x,y,z呼び出すことができる変数の最大数が必要な場合

max (max x y) z

しかし、それは多数の要素に対して冗長です。

1つの方法は、リストで再帰的に実行することです(「LearnYou a Haskell forGreatGood」の例を使用)

maximum :: Ord x => [x] -> x; 
maximum [] = error "maximum of empty list" 
maximum (x:[]) = x
maximum (x:xs) = max x (maximum(xs))

したがって、これを使用して、配列を作成してから、このような関数を作成して配列を操作する必要があります。これを行うためのより良い方法はありますか?

4

3 に答える 3

4

あなたが話しているパターンは「配列を操作する関数」ではなく、一般的な再帰パターンです。

もちろん、例えばフォールドのように、再帰的なパターンを処理する機能があります。
次に、最大関数を次のように再定義できます。

maximum xs = foldl' max 0 xs -- assuming all the value are upper than 0.   

リストの値の制限が気になる場合は、シード(上位0)をリストの最初の要素に置き換えるfoldl'、foldl1'のバリアントを使用できます。

maximum xs = foldl1' max xs

ほとんどすべての再帰構造は折り畳み可能です(リスト、ツリー、グラフ...)。
ただし、これらは他の再帰パターンであり、マップまたはフィルターを使用して利用できます。

とにかく、foldを使用した再帰の良い紹介、fold
の普遍性と表現力に関するチュートリアル

于 2013-03-18T11:48:21.127 に答える
2

zurglの答えに追加するために、Haskellにはコンテナ用の型クラスFoldableがあります。ユーティリティメソッドがあります

maximum :: (Foldable t, Ord a) => t a -> a

単に次のように定義されます

maximum = foldr1 max

したがって、実装するコンテナタイプFoldable(で示されるt)および順序付け(a)のある要素タイプであれば、この単一の関数を使用できます。つまり、データ型がその要素に対して折りたたみ操作を実装している場合、そのデータ型に対する任意の集計関数を同様の方法で定義できます。

于 2013-03-18T13:33:45.703 に答える
1

3つ以上の変数で2つの変数の関数を呼び出すための最良の方法は何ですか?

さて、ここで見てみましょう。ラケットでは、マクロを使うと思います。

#lang racket

(define-syntax apply*
  (syntax-rules ()
    [(apply* f x y)
     (f x y)]
    [(apply* f x y rest ...)
     (apply* f (f x y) rest ...)]))

(define (plus a b) (+ a b))
(apply* plus 1 2 3 4 5) ;; => 15

ここでは、apply*フォームが2つの引数の関数を取り、任意の長さの引数のリストでそれを呼び出すと見なしました。これは文字通りに展開(apply* max x y z)され(max (max x y) z)、きれいなコードを記述して、マクロエキスパンダーに詳細なコードに変換させることができます。


ただし、Haskellマクロは扱いが面倒で、むしろ一義的です。それでは、代わりに関数を使用しましょう。この関数はどのようになりますか?

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

最初の引数は2引数の関数で、同じタイプの2つのものを受け取り、そのタイプの物を吐き出します。これは、目的の結果からわかります。max (max x y) z、出力は入力と同じタイプである必要があります。Haskellでは変数アリティの関数を定義できないので、それをシミュレートするために、引数のリスト[a]を受け取る関数を記述します。

止まる。フーグルタイム!http://haskell.org/hoogleで型署名を検索すると(a -> a -> a) -> [a] -> a、これが呼び出され、すでに実装されていることがわかります。foldl1

于 2013-03-18T17:25:32.287 に答える