1

この関数の型を導出する必要があります。

func x = map -1 x

そして、ヒントを使用してラムダ式に変更する方法をすでに見つけました。

func = \x -> (map) - (1 x)

そのように表現すれば問題なく、オリジナルと同じタイプになりますが、なぜこのようにグループ化されているのかわかりません。誰かがそれを説明できますか?

たとえば、次のようにしないのはなぜですか。

func = \x -> (map - 1) x

または似たようなもの。

役に立たない関数などであることはわかっていますが、関数を変更することはできません。その型を派生させるだけです。

この関数をファイルに記述すると、たとえば、test.hs がインタープリターでfunc x = map -1 x 使用:t funcされ、次のように応答されます。

func :: (Num (t -> (a -> b) -> [a] -> [b]),
         Num ((a -> b) -> [a] -> [b])) =>
         t -> (a -> b) -> [a] -> [b]
4

3 に答える 3

4

私は今、あなたが理由を尋ねるつもりだったと信じています

func x = map -1 x

タイプを持ち、式(Num (t -> (a -> b) -> [a] -> [b]), Num ((a -> b) -> [a] -> [b])) => t -> (a -> b) -> [a] -> [b]を括弧で囲んでそのタイプにする方法。

まず、スペースは Haskell の演算子であり、すべての中で最も優先順位が高いことを認識する必要があります。

スペースの代わりに使用してみましょう#。最高の優先順位で使用できます。

infixl 9 #
f # x = f x

演算子なしでスペースを # に置き換えることができます。

func x = map - 1 # x

1 と x の間のスペースは、演算子のない唯一のスペースだったため (-は と の間mapにあり1ます)。

#は よりも優先順位が高いので-

func x = map - (1 # x)

または同等に

func x = map - (1 x)

もう一つの例

func2 x = map (-1) x
> :t func2
func2 :: Num (a -> b) => [a] -> [b]

これは次のように変換されます

func2' x = map # (-1) # x

しかし、なぜ と の間に # がない-1でしょうか? この場合、次のような-数値リテラルの前に:1negate

> (-1)
-1
> (negate 1)
-1
> (subtract 1)
<interactive>:73:1:
    No instance for (Show (a0 -> a0))
      arising from a use of `print'
    Possible fix: add an instance declaration for (Show (a0 -> a0))
    In a stmt of an interactive GHCi command: print it

したがって、この関数は 1 のマイナスをリストにマップしようとしています。それが機能するには、負の 1 が関数である必要があります。そのため、関数の数値インスタンス (Num (a->b) =>型の先頭) が必要です。

于 2013-05-28T18:16:45.747 に答える
2

しかし、なぜこのようにグループ化されているのかわかりません。誰かがそれを説明できますか?例では、なぜそうではないのですか:

   func = \x -> (map - 1) x

優先順位。言語定義では、(接頭辞) 関数の適用の優先順位がどの中置演算子の優先順位よりも高いことが指定されているため、

map -1 x

は、中置演算子(-)を 2 つのオペランドmapおよび1 xに適用したものとして3 + 4 * 5解析3 + (4 * 5)されます。(*)(+)

于 2013-05-28T17:44:37.700 に答える