1

I defined :

type Network = [(Matrix Double,Vector Double)]

where Matrix and Vector are from the hmatrix library. From the documentation of hmatrix it seems to me that Matrix Double and Vector Double are already instances of Num. Since I need to add and subtract Networks quiet a lot I also want Network to be an instance of Num. I tried

instance Num Network where
  (+) = zipWith (\(m,v) (n,w) -> (m+n,v+w))
  (-) = zipWith (\(m,v) (n,w) -> (m-n,v-w))
  (*) = zipWith (\(m,v) (n,w) -> (m*n,v*w))

but I am getting the error : Illegal Instance declaration.

AndyM
  • 51
  • 5
  • 1
    You need to turn on the `FlexibleInstances` language extension to create instances over type synonyms like the one you’ve written. The GHC error message might even suggest this (along with `TypeSynonymInstaces`, though `FlexibleInstnaces` implies the former). – Alexis King Jul 21 '16 at 16:59
  • 1
    @AlexisKing: Could you put that as an answer? It actually answers the question and it'll have better visibility. – Tikhon Jelvis Jul 21 '16 at 17:24
  • 1
    Please, just don't do this. It's not a good idea. A vector is not a number; element-wise multiplication doesn't have semantics that make sense for general vectors. And almost certainly not for networks, either. It may well make sense to give it a [`VectorSpace`](http://hackage.haskell.org/package/vector-space-0.10.2/docs/Data-VectorSpace.html) instance, though, but you should definitely wrap it in a `newtype`. – leftaroundabout Jul 22 '16 at 00:18
  • Note that when you define an instance you should define **all** the operations of the class. This includes, for example, `signum` and `abs`. Failing to do so may cause your programs to crash because some piece of code actually uses these and they end up `undefined`. – Bakuriu Jul 22 '16 at 09:28

1 Answers1

5

Alexis King's comment is correct to get your current code to compile. However, it might be better practice to make a newtype for Network - that way you don't need to use any language extensions at all.

newtype Network = Network [(Matrix Double,Vector Double)]

instance Num Network where
  (Network n1) + (Network n2) = Network $ zipWith (\(m,v) (n,w) -> (m+n,v+w)) n1 n2
  (Network n1) - (Network n2) = Network $ zipWith (\(m,v) (n,w) -> (m-n,v-w)) n1 n2
  (Network n1) * (Network n2) = Network $ zipWith (\(m,v) (n,w) -> (m*n,v*w)) n1 n2
Alec
  • 31,829
  • 7
  • 67
  • 114
  • thanks for the answer. What does the function NetWork do? – AndyM Jul 21 '16 at 22:33
  • `newtype` is functionally [almost](http://stackoverflow.com/questions/5889696/difference-between-data-and-newtype-in-haskell) identical to `data`, but with only a single constructor that has one field. You can sort of think of `Network` as the constructor for this type. – Alec Jul 21 '16 at 23:07
  • @AndyM Why yes it should. What a typo! Corrected. – Alec Jul 21 '16 at 23:22