26

GHCI は の型を与えてくれます1 ++ 2:

$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :t 1 ++ 2
1 ++ 2 :: Num [a] => [a]

しかし、これは明らかに間違っています。タイプチェックするだけでなく、評価しようとすると、正しく失敗します。

Prelude> 1 ++ 2

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

何を与える?

4

2 に答える 2

25

しかし、これは明らかに間違っています。

いいえ、完全に正しいです。

のタイプ(++)

(++) :: [a] -> [a] -> [a]

整数リテラルの型は

1 :: Num n => n

したがって、[a]の引数が持つ必要のある型は、リテラルが持つ(++)型と統一され、次のようになります。Num n => n

1 ++ 2 :: Num [a] => [a]

インスタンスを持つリスト型があるNum場合、その式も評価できます。

しかし、デフォルトでは、Num利用可能なリスト型のインスタンスがないため、それを評価しようとすると、ghci は のNumインスタンスが見つからないと文句を言います[a]

例えば:

Prelude> instance Num a => Num [a] where fromInteger n = Data.List.genericReplicate n 1 

<interactive>:2:10: Warning:
    No explicit method or default declaration for `+'
    In the instance declaration for `Num [a]'

<interactive>:2:10: Warning:
    No explicit method or default declaration for `*'
    In the instance declaration for `Num [a]'

<interactive>:2:10: Warning:
    No explicit method or default declaration for `abs'
    In the instance declaration for `Num [a]'

<interactive>:2:10: Warning:
    No explicit method or default declaration for `signum'
    In the instance declaration for `Num [a]'
Prelude> 1 ++ 2 :: [Int]
[1,1,1]
于 2013-02-23T14:32:52.843 に答える
16

誰かリストを数値として扱うように定義できるため:

instance Num a => Num [a] where
 (+) = zipWith (+)
 (*) = zipWith (*)
 (-) = zipWith (-)
 negate = map negate
 abs = map abs
 signum = map signum
 fromInteger x = [fromInteger x]

次に、入力したものが機能します。

  1++2 == fromInteger 1++fromInteger 2 == [1]++[2]

(このNumインスタンスがあまり意味をなさないというわけではありません..)

于 2013-02-23T15:54:42.323 に答える