Question

Below the code from here Fun with Type Functions

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, TypeFamilies #-}

-- Start basic
class Add a b where
  type SumTy a b
  add :: a -> b -> SumTy a b

instance Add Integer Double where
  type SumTy Integer Double = Double
  add x y = fromIntegral x + y

instance Add Double Integer where
  type SumTy Double Integer = Double
  add x y = x + fromIntegral y

instance (Num a) => Add a a where
  type SumTy a a = a
  add x y = x + y
-- End basic

This is the code which I'm trying to run:

main = print $ show (add 1 1)

This is the result:

No instance for (Show (SumTy a0 b0))
      arising from a use of `show'
    Possible fix: add an instance declaration for (Show (SumTy a0 b0))
    In the second argument of `($)', namely `show (add 1 1)'
    In the expression: print $ show (add 1 1)
    In an equation for `main': main = print $ show (add 1 1)

I've tried few things like putting "data" everywhere:

Result 1

Not a data constructor: `a'

Result 2 (after removing "instance (Num a)")

Multiple declarations of `Double'
Declared at: ...

like adding some function:

class Add a b where
    type SumTy a b
    add :: a -> b -> SumTy a b
    s :: SumTy a b -> String

instance Add Integer Double where
    type SumTy Integer Double = Double
    add x y = fromIntegral x + y
    s (SumTy _ x) = show x

main = print $ show (s (add 1 2.0) )

with this result:

Not in scope: data constructor `SumTy'

As you may have noticed I'm stuck so any help is priceless for me. :)

Was it helpful?

Solution

The problem is that there is not enough context to determine which instance of Add to use, and hence the type of the result cannot be determined. Since ghc doesn't know which types to use, it reports the most generic problem, there's no Show instance for a generic SumTy a b:

No instance for (Show (SumTy a0 b0))
      arising from a use of `show'
    Possible fix: add an instance declaration for (Show (SumTy a0 b0))
    In the second argument of `($)', namely `show (add 1 1)'
    In the expression: print $ show (add 1 1)
    In an equation for `main': main = print $ show (add 1 1)

The suggested "Possible fix" isn't what is required here, though. What you need is to specify the types of the arguments to add, so that the instance to use can be determined, and thus the result type:

*TyFun> show (add (1 :: Int) (1 :: Int))
"2"
*TyFun> show (add (1 :: Integer) (1 :: Integer))
"2"
*TyFun> show (add (1 :: Integer) (1 :: Double))
"2.0"
*TyFun> show (add (1 :: Integer) (1 :: Float))

<interactive>:7:1:
    No instance for (Show (SumTy Integer Float))
      arising from a use of `show'
    Possible fix:
      add an instance declaration for (Show (SumTy Integer Float))
    In the expression: show (add (1 :: Integer) (1 :: Float))
    In an equation for `it':
        it = show (add (1 :: Integer) (1 :: Float))

<interactive>:7:7:
    No instance for (Add Integer Float) arising from a use of `add'
    Possible fix: add an instance declaration for (Add Integer Float)
    In the first argument of `show', namely
      `(add (1 :: Integer) (1 :: Float))'
    In the expression: show (add (1 :: Integer) (1 :: Float))
    In an equation for `it':
        it = show (add (1 :: Integer) (1 :: Float))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top