0

次の型定義があります。

data NumList n = NumList [Rational]

次に、コードでいくつかの NumLists を次のように定義します。

n1 = NumList [1, 2, 3]
n2 = NumList [4, 5, 6]

私がやりたいことはこれです:

n3 = n1 + n2 -- Should be [5, 7, 9]

私はこれを次のように定義しようとしました:

toList :: NumList n -> [Rational]
toList (NumList n) = n

(+) :: NumList -> NumList -> NumList
(+) x y = if length x == length y
          then
              zipWith (+) toList x toList y -- This probably isn't right, but I'll debug this later
          else
              error "NumLists must be same length to add"

私が得るエラーは次のとおりです。

Ambiguous occurrence `+'
It could refer to either `NumList.+',
                             defined at NumList.hs:7:5
                          or `Prelude.+'

NumPrelude.+ はクラスに適用され、NumList.+ は NumList 型にのみ適用されるため、これがどのように曖昧なのかわかりません。これに関するガイダンスはありますか?また、ちょっとしたおまけ質問: パターン マッチングを使用して (+) 関数から if 式を削除する方法はありますか?

4

1 に答える 1

2

(+)現在のエラーは、プレリュード用とあなた用の2 種類のs が定義されていることです。これは、型NumListのインスタンスを作成することで修正できます。Num

instance Num NumList where
  (+) nl1 nl2 = implementPlus
  (*) nl1 nl2 = implementTimes
  (-) nl1 nl2 = implementMinus
  abs nl = NumList (map abs (toList nl))
  signum nl = NumList (map signum (toList nl))
  fromInteger i = NumList [fromInteger i]

今、追加が呼び出さimplemenPlusれ、すべてが素晴らしいものになります. 追加のボーナスとして、数値リテラルを書くこともできます。haskell はそれらが であると推測し、それらNumListを 1 つの要素のリストに変換します。これは、それらをたくさん書くのに非常に便利です。

また、おまけの質問については、次のように書きます

(NumList n1) + (NumList n2) = NumList $ zipWith (+) n1 n2

これは、結果が最短のリストの長さであるということです。本気で爆破したいなら

 (NumList n1) + (NumList n2) |length n1 == length n2 =
                                NumList $ zipWith (+) n1 n2
                             | otherwise             = 
                                error "You done goofed"

これはガードを使用するだけです。それらを強化したものと考えてくださいif。そしてotherwise、単純に次のように定義されます

otherwise = True

前奏で。

于 2013-10-19T02:49:43.733 に答える