How to get the best polymorphic type inference in Haskell for this example?

I have the following data type:

data PValue = IV Int | BV Bool | SV String
            deriving (Show, Eq)

I want to write a function that generates PValue from Int, Bool or String, for example:

> loadVal 3
IV 3

> loadVal True
BV Bool

> loadVal "Ha"
SV "Ha"

Since the argument loadVal is polymorphic, I tried to create a class:

class PValues v where
  loadVal :: v -> PValue

instance PValues Int where
  loadVal v = IV v

instance PValues Bool where
  loadVal v = BV v

instance PValues String where
  loadVal s = SV s

This works, except for Int:

> loadVal "Abc"
SV "Abc"
> loadVal False
BV False
> loadVal 3

<interactive>:8:1:
    No instance for (PValues v0) arising from a use of `loadVal'
    The type variable `v0' is ambiguous
    Note: there are several potential instances:
      instance PValues String -- Defined at Types.hs:22:10
      instance PValues Bool -- Defined at Types.hs:19:10
      instance PValues Int -- Defined at Types.hs:16:10
    In the expression: loadVal 3
    In an equation for `it': it = loadVal 3

<interactive>:8:9:
    No instance for (Num v0) arising from the literal `3'
    The type variable `v0' is ambiguous
    Note: there are several potential instances:
      instance Num Double -- Defined in `GHC.Float'
      instance Num Float -- Defined in `GHC.Float'
      instance Integral a => Num (GHC.Real.Ratio a)
        -- Defined in `GHC.Real'
      ...plus 8 others
    In the first argument of `loadVal', namely `3'
    In the expression: loadVal 3
    In an equation for `it': it = loadVal 3

I understand that this is because 3in itself it has an ambiguous type (maybe Int, Floatetc.). Is there a way to force this type to be deduced without explicitly annotating it on the call site?

+4
source share
1 answer

@AndrewC . loadVal 3 :

instance PValues Integer where
  loadVal v = IV (fromInteger v)

, Text , , String Text:

data PValue = IV Int | BV Bool | SV Text
            deriving (Show, Eq)

instance PValues String where
  loadVal s = SV (pack s)

instance PValues Text where
  loadVal s = SV s

, , Text, pack.

+4

All Articles