让函数根据参数的值返回不同的类型

鉴于此接口:

{-# LANGUAGE DataKinds      #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies   #-}
module Tlf where

import           Data.Dynamic  (Dynamic, fromDyn, toDyn)
import           Data.Kind     (Type)
import           Data.Proxy    (Proxy (Proxy))
import           Data.Typeable (Typeable)

data Q = Q1 | Q2
       deriving (Show)

data R1 = R1 deriving (Show)
data R2 = R2 deriving (Show)

newtype TL (a :: [Type]) = TL { unTL :: Dynamic }

someFun :: Q -> TL '[R1, R2]
someFun Q1 = (TL . toDyn) R1
someFun Q2 = (TL . toDyn) R2

我想编写一个运行someFunc并提取返回值的函数。这有效:

myQ :: (Typeable a) => Proxy a -> Q -> a
myQ _ q = (fromDyn . unTL . someFun) q (error "This shouldn't happen!")
> myQ (Proxy :: Proxy R1) Q1
R1
> myQ (Proxy :: Proxy R1) Q1
R1

但是额外的东西Proxy*Tlf> myQ (Proxy :: Proxy R2) Q1 *** Exception: This shouldn't happen!

de>是多余的,它并不像它应该的那样安全

*Tlf> myQ (Proxy :: Proxy R2) Q1
*** Exception: This shouldn't happen!

问题是我知道Q1会产生R1。所以我写了这个:

但现在我被困在如何把这些碎片放在一起。我试过:

但是 ghc 说不:

    • Expected kind ‘Q’, but ‘q’ has kind ‘*’
    • In the first argument of ‘FunRes’, namely ‘q’
      In the type signature: myQ' :: forall q. q -> FunRes q

我还尝试了其他一些事情,但我总是偶然发现上面给出的错误。

以上是让函数根据参数的值返回不同的类型的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>