如何创建具有多态数据的数组?

How can I create an array with polymorphic data?

我正在尝试这样做

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

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

但是出现错误

Could not match type

Int

with type

a0

存在类型在 PureScript 中的工作方式与在 Haskell 中的工作方式不同,因此我们通常使用 purescript-exists 库来处理此类事情。

使用 Exists 的等价物是:

import Data.Exists (Exists(), mkExists)

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

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

我想在这种情况下你可能根本不需要 FooWrapper 并且可以只需要一个 Exists Foo.

的数组

我想知道 Phil Freeman 建议的方法是如何工作的,所以我试了一下。这是一个使用 rank-n 类型存储类型 class 实例及其值的工作示例。

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

newtype 并不是存储所必需的,但我想为类型本身创建一个 Show 的实例。