Haskell - let binding selects the wrong instance

The next test took me by surprise

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Test where

class Type t where
    encodeToField :: t -> String

class Rec r where
    encodeToRec :: r -> String

data X a b = X a b

instance (Type t) => Rec t where
    encodeToRec = encodeToField

instance (Type t, Rec r) => Rec (X t r) where
    encodeToRec (X t r) =
        let x = encodeToField t
            y = encodeToRec r
         in x ++ y

ghc fails with

Test.hs:19:17
Could not deduce (Type r) arising from a use of `encodeToRec'
from the context (Type t, Rec r)

For some reason, ghc wants to use the instance Type t => Rec tin y = encodeToRec rinstead of just accepting Rec rinstance declarations from the context.

If I avoid let bindings and write instead

instance (Type t, Rec r) => Rec (X t r) where
    encodeToRec (X t r) = encodeToRec t ++ encodeToRec r

it compiles.

Is this a bug in ghc or should this behavior be expected due to the language extensions used?

+4
source share
1 answer

: , , GHC . SO . , ​​- ( ).

+1

All Articles