为Num定义实例

时间:2018-02-04 20:53:26

标签: haskell

我有一个带有类型声明的模块和一些此类型的函数

module Stream where

import Prelude ((+), (-), (<), (++), (*), otherwise, id)
import qualified Prelude as P

infixr 1 :&


data Stream a = a :& Stream a


instance P.Show a => P.Show (Stream a) where
  show xs = showInfinity (P.show (take 5 xs)) where
    showInfinity xs = P.init xs ++ "..."

head :: Stream a -> a
head (x:&_) = x


tail :: Stream a -> Stream a
tail (_:&xs) = xs


(!!) :: Stream a -> P.Int -> a
(!!) xs 0 = head xs
(!!) xs n = (tail xs) !! (n - 1)


take :: P.Int -> Stream a -> [a]
take 0 xs = []
take n xs = (head xs) : (take (n - 1) (tail xs))


map :: (a -> b) -> Stream a -> Stream b
map f xs = f (head xs) :& map f (tail xs)


zipWith :: (a -> b -> c) -> Stream a -> Stream b -> Stream c
zipWith f xs ys = f (head xs) (head ys) :& zipWith f (tail xs) (tail ys)


iterate :: (a -> a) -> a -> Stream a
iterate f a = a :& iterate f (f a)

现在我想为我的类型声明Num类的实例。

instance P.Num a => P.Num (Stream a) where
  (+)         xs ys  = zipWith (+) xs ys
  (-)         xs ys  = zipWith (-) xs ys
  (*)         xs ys  = zipWith (*) xs ys
  negate      xs     = map P.negate xs
  abs         xs     = map P.abs xs
  signum      xs     = map P.signum xs
  fromInteger x      = P.error "Not implemented yet" --constStream x

函数*-*可以按我的方式工作,但函数negateabssignum不存在。

GHCi, version 8.2.2: http://www.haskell.org/ghc/  :? for help
Prelude> :l Stream
[1 of 1] Compiling Stream           ( Stream.hs, interpreted )
Ok, one module loaded.
*Stream> s1 = iterate (\x -> x + 1) 1
*Stream> negate s1

<interactive>:3:1: error:
    • Variable not in scope: negate :: Stream P.Integer -> t
    • Perhaps you meant ‘P.negate’ (imported from Prelude)

1 个答案:

答案 0 :(得分:3)

GHCi尝试提供对绑定的相同访问权限,就好像我们在我们加载的模块中一样。由于该模块具有明确的Prelude导入

import Prelude ((+), (-), (<), (++), (*), otherwise, id)
import qualified Prelude as P

然后GHCi还要求用户键入P.negate。毕竟,模块源代码也需要这样。

在GHCi中,我想也可以import Prelude,以便让所有绑定再次可用,而不必使用P.限定它们。