11

私はとても眠いので、次のコードを書きました(混乱を示すために変更されました):

fac s = take 10 [s, s `mod` 1 ..]

maxFactor x = if (s == [])
              then x
              else head    <-- this should be 'head x' instead of just 'head'
  where s = fac x

ただし、このghciへのロード(およびコンパイル)は問題ありません。私が実行したときmaxFactor 1、それは(もちろん)不平を言います:

<interactive>:0:1:
    No instance for (Integral ([a0] -> a0))
      arising from a use of `maxFactor'
    Possible fix:
      add an instance declaration for (Integral ([a0] -> a0))
    In the expression: maxFactor 1
    In an equation for `it': it = maxFactor 1

<interactive>:0:11:
    No instance for (Num ([a0] -> a0))
      arising from the literal `1'
    Possible fix: add an instance declaration for (Num ([a0] -> a0))
    In the first argument of `maxFactor', namely `1'
    In the expression: maxFactor 1
    In an equation for `it': it = maxFactor 1

しかし、私はこの振る舞いを理解していません:

facのタイプは次のとおりです。

fac :: Integral a => a -> [a]

maxFactorのタイプは次のとおりです。

maxFactor :: Integral ([a] -> a) => ([a] -> a) -> [a] -> a

これは次のことを意味するのではありません:

  1. の最初の入力facは型クラスでなければなりませんIntegral(例fac 10)。
  2. の定義にはmaxFactor、がありfac x、xも型クラスでなければならないIntegralので、したがって、maxFactorの型はmaxFactor :: (Integral a) => a ->...のようなもので始まり、次に何か他のものになりますか?ただし、その場合は、の戻り値がまたはであるため、このコードがコンパイルされるのはなぜmaxFactorですかxheadこの推論の行に従うと、同じタイプではありません。

ここで何が欠けていますか?

事前にご入力いただきありがとうございます。

4

2 に答える 2

11

お気づきのとおり、fac内部で関数を使用すると、のタイプに制約がmaxFactor追加されます。したがって、タイプである必要があります。Integral axxIntegral a => a

さらに、コンパイラーは、タイプまたは。を持つ。をmaxFactor返すことを確認します。したがって、より具体的なタイプが必要であり、タイプもhead[a]->axxIntegral ([a]->a) => ([a]->a)maxFactor

maxFactor :: Integral ([a] -> a) => ([a] -> a) -> ([a] -> a)

それはまさにあなたが得たものです。これまでのところ、この定義に「間違った」ものはありません。Integralタイプのインスタンスを作成できた場合は、問題なく([a]->a)呼び出すことができますmaxFactor。(明らかにmaxFactor、期待どおりに機能しません。)

于 2012-04-10T16:19:07.507 に答える
9

maxFactorコンパイラでは、関数の引数は必ず(句内の)xと同じ型であると推測されます。あなたも呼び出すので(それは順番に呼び出す)、それはまたいくつかのクラスタイプであると推測します。その結果、コンパイラはタイプを推測しますheadiffacxmodxIntegral

maxFactor :: Integral ([a] -> a) => ([a] -> a) -> [a] -> a

これにはhead、整数のような引数が必要です...これは本物ではない可能性があります。

そのコードをGHCiにロードできるという事実は、通訳者の癖だと思います。上記のコードをコンパイルしただけでは失敗します。

編集:問題は、型チェッカーがコードを理解できることだと思いますが、おそらくそれを使用するための賢明な方法はありません。

于 2012-04-10T15:54:49.623 に答える