5

次の関数が機能する理由がわかりません。

isLongerThanN :: Integral n => n -> [a] -> Bool
isLongerThanN n xs = length xs > fromIntegral n

しかし、以下はそうではありません:

isLongerThanN' :: Integral n => n -> [a] -> Bool
isLongerThanN' n xs = length xs > n

エラーをスローする

Could not deduce (n ~ Int)
    from the context (Integral n)
      bound by the type signature for
                 isLongerThanN' :: Integral n => n -> [a] -> Bool
      at blah.hs:140:1-35
      `n' is a rigid type variable bound by
          the type signature for
            isLongerThanN' :: Integral n => n -> [a] -> Bool
          at blah.hs:140:1
    In the second argument of `(>)', namely `n'
    In the expression: length xs > n
    In an equation for `isLongerThanN'':
        isLongerThanN' n xs = length xs > n

(私はおそらく誤解している)

fromIntegralは変数 n の型を効果的に拡張しているため、どちらかといえば、逆になると思います。

4

1 に答える 1

12

うまくいかない表現を考える

isLongerThanN' :: Integral n => n -> [a] -> Bool
isLongerThanN' n xs = length xs > n

nは任意の integer-y 型にできるため、IntegerorWordまたはを渡すことができますInt(>)には型Ord a => a -> a -> Boolがあるため、左右のオペランドの両方が同じ型でなければなりません。length xsを返すIntので、この型はそれでなければなりません。ただし、は必ずしも ではなく、n任意の になる可能性があるため、を に変換できるようにする何らかの方法が必要です。これは何をするかです(それがanyになることも許可するという事実は基本的に無関係です)。IntegralIntnIntfromIntegralnNum

作業バージョンを次のように拡張できます。

toInt :: Integral n => n -> Int
toInt = fromIntegral

isLongerThanN :: Integral n => n -> [a] -> Bool
isLongerThanN n xs = length xs > toInt n

これにより、特別なバージョンの を使用していることが明確になりますfromIntegral

( の結果がの型と一致するisLongerThanN n xs = fromIntegral (length xs) > nため、 も機能することに注意してください。)lengthn

于 2012-04-29T03:24:06.667 に答える