【问题标题】:Unable to create Dynamic from GADT Expression Type in Haskell无法从 Haskell 中的 GADT 表达式类型创建动态
【发布时间】:2017-12-06 21:09:35
【问题描述】:

我在 Haskell 中有以下内容(作为最小示例)。

{-# LANGUAGE GADTs #-}
import Data.Dynamic    

data Expr a where
  Lift  :: (Show a) => a -> Expr a --Lift some type into Expr
  Lam   :: (Expr a -> Expr b) -> Expr (a -> b)
  Const :: Expr a -> Expr b -> Expr a

当我尝试从以下创建动态时,我收到一个错误,我不确定如何更正。

--This is the code
toDyn $ (Lam (Const (Lift 1)))
-- This is the error
-- • No instance for (Typeable b0) arising from a use of ‘toDyn’
-- • In the expression: toDyn (Lam (Const (Lift 1)))
--   In an equation for ‘it’: it = toDyn (Lam (Const (Lift 1)))

有没有办法解决这个问题?其他构造函数都可以正常工作(我的实际程序有超过 100 个其他构造函数!)但是 Const 真的给我带来了麻烦!

【问题讨论】:

  • 我猜你需要给那个(Lam ...)提供一个特定的类型,否则太笼统了,只能给一个多态类型。基本上,您必须在Const 应用程序中选择b 是什么。

标签: haskell dynamic gadt


【解决方案1】:

错误是说Const 的第二个参数的类型,即被丢弃的那个,需要是Typeable。但它是一个完全通用的类型变量,没有 Typeable 约束。如果你写类似

toDyn (Const (Lift 1) :: Expr Int -> Expr Int)

toDyn (Lam (Const (Lift 1) :: Expr Int -> Expr Int))

两者都有效。

【讨论】:

  • 有没有办法可以给通用变量一个可键入的约束?我试过data Expr a where Const :: (Typeable a, Typeable b) => Expr a -> Expr b -> Expr a,但运气不佳。我什至尝试过为 Expr 自动派生 Typeable。
  • @Donovan 我只是在玩这个,但我不认为Typeable 那样工作 - 我认为问题在于类型变量是存在的。
  • @Donovan 最后,Typeable 实例需要有一个特定的类型。但由于存在性,它永远无法提供。至少我认为这就是正在发生的事情。如果你直接在像toDyn (\a -> a) 这样的多态函数上尝试toDyn,你会得到类似的错误。而toDyn (\a -> a + a) 可以,因为Num 约束的默认设置。
  • 谢谢你,也许我可以尝试一些花哨的东西,使用类型族从自定义的类似动态的结构中提取正确的类型。
猜你喜欢
  • 1970-01-01
  • 2013-09-12
  • 2019-01-25
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多