2

私は Haskell で次のようなものを書こうとしています:

length . nub . intersect

しかし、うまくいきません。

*Main Data.List> :t intersect
intersect :: Eq a => [a] -> [a] -> [a]
*Main Data.List> :t nub
nub :: Eq a => [a] -> [a]
*Main Data.List> :t length
length :: [a] -> Int

型に基づいて、私の理解ではintersect、 の型を返し、[a]に寄付しますnub。これは、 の型を正確に受け取り、to[a]の型も返します。最後に、戻り値は になります。どうしたの?[a]lengthInt

4

3 に答える 3

6

ここでの問題は、(ある意味で) intersect 2 つの引数を取ることです。

引数の 1 つを明示的に指定できます。

> let f a = length . nub . intersect a
> :t f
f :: Eq a => [a] -> [a] -> Int

または、次のような楽しい小さな演算子を使用できます(.:) = (.) . (.)

> let (.:) = (.) . (.)
> :t length .: (nub .: intersect)
length .: (nub .: intersect) :: Eq a => [a] -> [a] -> Int

括弧が不要なバージョンは次のとおりです。

import Data.List

infixr 9 .:

(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
(.:) = (.).(.)

f :: Eq a => [a] -> [a] -> Int
f = length .: nub .: intersect
于 2014-09-09T06:50:22.440 に答える
4

これは、 @CarstenKönig が言及(.) . (.)している前の質問のコメントに基づいていると思います。

まずlength . nub . intersect仕事ができない。あなたのタイプは次のとおりです。

(.)       ::         (b -> c) -> (a -> b) -> (a -> c)
length    ::         [a] -> Int
nub       :: Eq a => [a] -> [a]
intersect :: Eq a => [a] -> [a] -> [a] ~ [a] -> ([a] -> [a])

ご覧のとおり、intersectの型が間違っています。 のコンテキストで(.)は、型パラメーターはの最初の引数の型ではない にb置き換えられます。([a] -> [a])nub

于 2014-09-09T06:50:44.727 に答える
2

私はこれを言います:最初は「ばかげた」方法でコードを書き、次にそれをリファクタリングして使用します(.)。いくつかの練習の後、合成オペレーターは第二の性質のようになります。

したがって、最初に次のように記述します。

yourFunction xs ys = length (nub (intersect xs ys))

あなた(.)ができることは、最も内側の関数の最後の引数、すべての括弧を (構文的に) 取り除くことです。この場合、その引数はys次のとおりです。

yourFunction xs = length . nub . intersect xs
于 2014-09-09T19:33:42.033 に答える