1

3つの関数を取り、それらを組み合わせてリスト引数を変更する関数があります。

たとえば、テストケースの呼び出しは次のようになります。chaininit tail reverse "Haskell!" 出力はlleksaである必要があります

mapこの問題を関数の使用を含むいくつかの異なる方法で実行しようとしましたが、関連付けの問題が発生し続けました。だから私はしました

chain :: Ord a => [a] -> a
chain f g h x = f.g.h$x

エラーはCouldn't match expected type [t0 -> t1 -> t2 -> a0]

たとえば、書くようにGHCiに直接問題を入力すると、init.tail.reverse$"Haskell!"正しく機能します

3つの関数の引数を含める方法さえありますか?例では2つしか見ていません。

4

3 に答える 3

6

3 つの関数を構成する高階関数の最も一般的な型シグネチャは次のようになります。

chain :: (b -> c) -> (b1 -> b) -> (a -> b1) -> a -> c
chain f g h x = f.g.h$x

(定義を なしxで書くこともできます。

chain f g h = f.g.h

)。中間関数bとの戻り値の型b1は任意であることに注意してください。唯一の要件は、次の関数の引数の型と一致する必要があることです。今、あなたが呼ぶchain init tail reverse "Haskell!"なら、あなたは得るでしょう"lleksa"

関数の書き方は知っているが、適切な型がわからない場合は、GHCi に型を推測させることができます。そこに関数をロードして、たとえば:t chain(:tは の省略形です。 GHCi コマンド:typeを参照してください) と入力するだけです。


さらに進んで、任意の数の関数を構成することもできます。(ただし、この場合、型システムにより、一般的ではない型シグネチャが強制されます。)

chainN :: [a -> a] -> (a -> a)
chainN fs = foldr (.) id fs

この関数はatoから関数のリストをa取得し、それらを一緒に構成します。リストが空の場合、恒等関数だけを返します。あなたchainNとのようなものを書くことができます

chainN [init, tail, reverse] "Haskell!"
于 2012-12-05T08:25:35.150 に答える
1

プレリュードがあなたの機能を分析するとき:

chain f g h x = f.g.h$x

f関数、、、gおよびを受け取っていることを前提としていますh。なぜそれを想定しているのですか?.演算子の目的は関数を連鎖させることだからです。したがって、使用しているのは、関数をチェーンしているためです。

([a] -> a)関数が受け取り、返す必要のあるものとは異なる型シグネチャを関数に定義しました。1つの解決策は、型署名を指定せずにプレリュードに残すことです。別の解決策は、型署名を修正することです。

aただし、関数がリストを受け取り、を返すことを期待している場合はa、関数を次のように変更する必要があります。

chain :: (Ord a) => [a] -> a
chain (x:xs) = ...
于 2012-12-05T04:56:18.200 に答える