Why is the type system refusing my seemingly valid program?

后端 未结 2 946
清歌不尽
清歌不尽 2021-01-30 12:05

Mind this program:

class Convert a b where
    convert :: a -> b

data A = A deriving Show
data B = B deriving Show
data C = C deriving Show
data D = DA A | D         


        
2条回答
  •  清酒与你
    2021-01-30 12:30

    For that code to work, it would have to work with any argument of the same type. That is, if

    get (DB B) :: A
    

    works then

    get anyValueOfTypeD :: A
    

    has to work, including

    get (DC C) :: A
    

    which can not work because of a missing instance from C to A.

    The first line

    get anyValueOfTypeD :: B
    

    works because we do have all the three instances to convert A,B,C to B.

    I do not think there's any workaround that allows you to leave the type D as it is. If instead you can change that, you could use e.g.

    data D a = DA a | DB a | DC a
    

    (mind that it's quite different from the original), or even the GADT

    data D x where
      DA :: A -> D A
      DB :: B -> D B
      DC :: C -> D C
    

提交回复
热议问题