문제

Using the following type and class definitions, I do not understand why I get and error when creating the instance below.

I need MyMap to hold a map of heterogeneous values.

{-# LANGUAGE ExistentialQuantification #-}
module Scratch.SO_ExtistentialTypes where

import Data.Map

type MyMap a = Map String a

class MyClass c where 
    getMyMap :: forall a. c -> MyMap a

data MyData = forall a. MyData {
    myMap ::  MyMap a
}

instance MyClass MyData where
    getMyMap = myMap -- <= ERROR
도움이 되었습니까?

해결책

For one thing, the forall here is superfluous:

class MyClass c where 
    getMyMap :: forall a. c -> MyMap a

Type variables with no explicit binding are universally quantified at the outermost level, so this is exactly the same as just c -> MyMap a.

Beyond that, a universally quantified type is certainly not going to match an existentially quantified type. The type of getMyMap says that, given a value of type c, it will produce a value of type MyMap a for any possible choice of type a. On the other hand, the accessor myMap says that, given a value of type MyData, it will produce a value of type MyMap a for some specific but unknown type a.

It's not possible to have unwrapped existential types floating around by themselves (this would require an exists quantifier corresponding to forall), so there's no way to rewrite the type of getMyMap such that myMap is a valid implementation.

All you can do with something having an existential type is wrap it back up in another data type that hides the existential quantifier, or give it to a function that has an argument with a universally quantified type. For example, you can use length on a list [a] with a an existential type.

In your case, the values of the Map have existential type with no other structure or constraints, so they're pretty much useless and might as well be ().

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top