0

I am trying to do this

data Foo a = Foo a
data FooWrapper = FooWrapper (forall a. Foo a)

foo = [FooWrapper (Foo 0), FooWrapper (Foo "")]

But there is an error

Could not match type

Int

with type

a0
2
  • What is it you're trying to do? I ask because an array with elements of different types isn't going to be very useful without some sort of constraint on the element types. This is usually considered to be an anti-pattern in Haskell. Commented Mar 14, 2016 at 17:15
  • data Foo a b = Foo a b foo1 :: Foo Int String foo2 :: Foo Int Int I what to create a function that could work with array of Foo even if their second parameters have the different types doSomething [foo1, foo2] because the function only use first parameter. Commented Mar 14, 2016 at 17:40

2 Answers 2

1

Existential types don't quite work the same in PureScript as they do in Haskell, so usually we use the purescript-exists library for this kind of thing.

The equivalent using Exists would be:

import Data.Exists (Exists(), mkExists)

data Foo a = Foo a
data FooWrapper = FooWrapper (Exists Foo)

foo = [FooWrapper (mkExists (Foo 0)), FooWrapper (mkExists (Foo ""))]

I suppose in this case you probably don't need FooWrapper at all and could just have an array of Exists Foo.

Sign up to request clarification or add additional context in comments.

3 Comments

Is it possible to use type class constrains with Exists? data FooWrapper = FooWrapper (forall a. Show a => Foo a) For example, how can I get ["0", ""] :: Array String from [(mkExists (Foo 0)), (mkExists (Foo ""))]?
Yes, you need to add the dictionary into the wrapper type somehow. An alternative is to encode the existential type using forall, e.g. type SomeShow = forall r. (forall a. Show a => a -> r) -> r.
@PhilFreeman Could you show a full code of getStrings stackoverflow.com/questions/36006483/… ?
0

I wanted to know how Phil Freeman's suggested approach works, so I gave it a try. This is a working example of storing a type class instance with its value by using a rank-n type.

module Example where

import Prelude (class Show, Unit, discard, pure, show, unit, ($))

import Effect (Effect)
import Effect.Console (log)


newtype Showable = Showable (forall r. (forall a. Show a => a -> r) -> r)

instance showShowable :: Show Showable where
  show (Showable f) = f show

mkShowable :: forall s . Show s => s -> Showable
mkShowable s = Showable (\f -> f s)

showables :: Array Showable
showables = [mkShowable 1, mkShowable "a string", mkShowable { foo : "bar" } ]

main :: Effect Unit
main = do
  log $ show showables
  pure unit

The newtype is not really necessary for storing, but i wanted to create an instance of Show for the type itself .

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.