2

私は Haskell の学習を開始し、素敵な演習を見つけました。それは次のとおりです。

grouping: Int -> [Student]->[(Team, Student)]
grouping teamNumber = zip ys
                      where ...

だから、演習は私が残りを埋めようとすることを望んでいます。この関数は次のことを行う必要があります: 例: grouping 2 ['Mark','Hanna','Robert','Mike','Jimmy'] = [(1,'Mark'),(2,'Hanna'),(1,'Robert'),(2,'Mike'),(1,'Jimmy')].

そのため、2 人の学生で構成されるチームを構築しています。最後の学生「ジミー」にはチームメイトがいません。

次に、事前定義された関数が何をするかについても調べますzip。2 つのリスト引数を取得し、リストの各要素をタプルに接続して、タプルのリストを作成します。

私の考え:1)「グラブ」と「無限」の2つの機能を構築しようとしています。彼らは次のように見えます:

grap :: Int -> [a] -> [a]
grab _ [] = []
grab n (x:xs) = if n <= 0 then [] else x : grab (n-1) xs  

infinite :: Num a => a -> [a]
infinite x = x : infinite(x+1)

だから、彼らがやっていることは次のとおりです。infinite私は無限リストを作成したいです。そして、その要素をgrap取る必要があります。ngrap 2 (infinite 1) = [1,2]

これら 2 つをwhere宣言の最初の行で使用して、上記の特定の機能を実行します。ので、私は持っています:

grouping: Int -> [Student]->[(Team, Student)]
grouping teamNumber = zip ys
                      where 
                      xs = grap teamNumber (infinite 1)

だから、xs今私の最初のリストzip、特に整数リストです。

しかし今、私の質問:zip事前定義された関数として、特に学生の名前のリストである 2 番目のリストも必要ですが、指定された関数では、zip に引数を 1 つだけ、つまりysリストとして与えます。どうすればそれを理解できますか?

4

3 に答える 3

1

Haskell では、以下は同等です。

f = (\x      y -> ..x..y..  )
f = (\x -> (\y -> ..x..y.. ))  -- this equivalence is known as "currying"
f     x =  (\y -> ..x..y.. )   -- partially applying f with x gives (\y->...)
f     x      y =  ..x..y..

((\x -> ...)もちろん、これは無名の、いわゆる「ラムダ」関数に対する Haskell の表記法です (\ギリシャ文字を思い起こさせるためλです。)

Haskell では、関数は他の値とまったく同じであるため、関数呼び出しや「関数ポインター」などに特別な構文はありません。型に関しては、上記は当然のことです。

f ::  a ->   b ->   t
f     x ::   b ->   t  -- the result of calling f w/ x (of type a) has type b->t
f     x      y ::   t  -- when f :: a->b->t, x :: a, y :: b, then f x y :: t

じっと見つめてください。

以上がカレーの話です。関数呼び出しは、Haskell では並置で示されるため、左に関連付けられます ( f x yis really ((f x) y))。また、Haskell の定義は自動的にカリー化されるため、型の矢印は右側に関連付けられます (a->b->c実際には ですa->(b->c))。

于 2014-05-13T09:28:06.933 に答える