标签: gadt

将 GADT 与 DataKinds 结合使用以实现函数中的类型级数据构造函数约束

我正在尝试将 GADT 与 DataKinds 结合使用,如下所示

\n
{-# LANGUAGE KindSignatures, DataKinds, GADTs #-}\nmodule NewGadt where\n\ndata ExprType = Var | Nest\n\ndata Expr (a :: ExprType) where\n  ExprVar :: String -> Expr Var\n  ExprNest :: Expr a -> Expr Nest\n\ndata BaseExpr\n  = BaseExprVar String\n  | BaseExprNest BaseExpr\n\ntranslate :: BaseExpr -> Expr a\ntranslate (BaseExprVar id) = ExprVar id\ntranslate (BaseExprNest expr) = ExprNest $ translate expr\n
Run Code Online (Sandbox Code Playgroud)\n

编译错误:

\n
/home/elijah/code/monty/src/NewGadt.hs:15:32: error:\n    \xe2\x80\xa2 Couldn\'t match type \xe2\x80\x98a\xe2\x80\x99 with \xe2\x80\x98\'Var\xe2\x80\x99\n      \xe2\x80\x98a\xe2\x80\x99 is a rigid type variable bound …
Run Code Online (Sandbox Code Playgroud)

haskell existential-type gadt data-kinds

5
推荐指数
2
解决办法
445
查看次数

如何从范围内的约束族派生类型类实例?

编辑:我提出了一个更具体的问题。谢谢这里的回答者,我认为后续问题可以更好地解释我在这里引入的一些困惑。

\n
\n

TL;DR我正在努力将约束证明放入表达式中,同时在构造函数上使用具有存在约束的 GADT。(这是一个严肃的口,抱歉!)

\n
\n

我将问题归结为以下几点。我有一个简单的 GADT,它表示名为 的点X和名为 的函数应用程序F。点X被限制为Objects

\n
data GADT ix a where\n  X :: Object ix a => a -> GADT ix a\n  F :: (a -> b) -> GADT ix a -> GADT ix b\n
Run Code Online (Sandbox Code Playgroud)\n

Constrained指的是其对象受某物约束的容器,并且Object某物。(编辑:我真正的问题涉及Category约束类别Cartesian中的类)

\n
-- | I can constrain the values within containers of …
Run Code Online (Sandbox Code Playgroud)

haskell constraints existential-type gadt quantified-constraints

5
推荐指数
1
解决办法
115
查看次数

异构列表的元素是否可能取决于前面元素的类型?

语境

我想对 Web 应用程序的路由进行建模,使其满足以下要求:

  1. 可以强制执行完整的定义
  2. 可以创建不完整的定义
  3. 可以检查不完整的定义是否“匹配”(即包含在)完整的定义。

作为使用的示例:

type root =
  | Fruit of fruit
  | Veggie of veggie
  
and fruit =
  | Apple of apple
  | Banana of banana
  
and veggie =
  | Carrot of carrot
  
and apple = { diameter: int; cultivar: string; }
and banana = { length: int }
and carrot = { length: int; color: [`Orange | `Purple] }
Run Code Online (Sandbox Code Playgroud)

有了这个,我们可以轻松创建和执行完整的定义:

let complete = Fruit (Apple { diameter = 8; cultivar = "Golden Delicious" })
Run Code Online (Sandbox Code Playgroud)

但无法创建不完整的定义 …

ocaml gadt heterogeneous-list

5
推荐指数
1
解决办法
138
查看次数

GADTs上的模式匹配

我为表达式创建了一个GADT.当我对具有约束的构造函数进行模式匹配时,类型检查器无法推断出对构造函数约束中使用的类型变量的约束.我认为代码和错误信息更具说明性.

{-# LANGUAGE GADTs, MultiParamTypeClasses #-}
import Data.Word

data Expr a where
  Value :: a -> Expr a
  Cast :: (Castable a b) => Expr a -> Expr b

class Castable a b where
  cast :: a -> b

instance Castable Word64 Word32 where
  cast = fromIntegral

instance (Show a) => Show (Expr a) where
  show (Cast e) = "Cast " ++ show e -- ERROR
Run Code Online (Sandbox Code Playgroud)

我得到的错误:

gadt.hs:16:30:
    Could not deduce (Show a1) arising from a use of `show'
    from …
Run Code Online (Sandbox Code Playgroud)

haskell typeclass gadt

4
推荐指数
1
解决办法
513
查看次数

用相应的符号标记字符串

我想要一个简单的方法来创建一个String标记自己.现在我可以这样做:

data TagString :: Symbol -> * where
    Tag :: String -> TagString s
    deriving Show

tag :: KnownSymbol s => Proxy s -> TagString s
tag s = Tag (symbolVal s)
Run Code Online (Sandbox Code Playgroud)

并使用它

tag (Proxy :: Proxy "blah")
Run Code Online (Sandbox Code Playgroud)

但这并不好,因为

  • 关于标签的保证仅tag由GADT提供.
  • 每次我想创建一个值时,我都必须提供一个类型签名,如果值是某个更大表达式的一部分,它将变得难以处理.

有没有办法改善这一点,最好是朝着相反的方向,即从?StringSymbol?我想写,Tag "blah"并有ghc推断类型 TagString "blah".

GHC.TypeLits提供了someSymbolVal看起来有点相关的函数,但是它生成了SomeSymbola Symbol而不是a ,我可以完全掌握如何使用它.

haskell types gadt

4
推荐指数
1
解决办法
409
查看次数

如何在OCaml中的各个模块之间使用GADT,而不会发出警告?

我有两个文件:gadt1.ml和gadt2.ml,第二个取决于第一个。

gadt1.ml:

type never
type _ t1 = A1 : never  t1 | B1 : bool t1
type _ t2 = A2 : string t2 | B2 : bool t2
let get1 : bool t1 -> bool = function B1 -> true
let get2 : bool t2 -> bool = function B2 -> true
Run Code Online (Sandbox Code Playgroud)

gadt2.ml:

let get1 : bool Gadt1.t1 -> bool = function Gadt.B1 -> true
let get2 : bool Gadt1.t2 -> bool = function Gadt.B2 -> true
Run Code Online (Sandbox Code Playgroud)

当我使用ocaml …

ocaml types pattern-matching compiler-warnings gadt

4
推荐指数
1
解决办法
150
查看次数

多态数据类型的函数

数据Foo a定义如下:

data Foo a where
  Foo :: (Typeable a, Show a) => a -> Foo a
  -- perhaps more constructors

instance Show a => Show (Foo a) where
  show (Foo a) = show a
Run Code Online (Sandbox Code Playgroud)

有些情况:

fiveFoo :: Foo Int
fiveFoo = Foo 5

falseFoo :: Foo Bool
falseFoo = Foo False
Run Code Online (Sandbox Code Playgroud)

我如何定义任何函数b -> Foo a,例如:

getFoo :: (Show a, Typeable a) => String -> Foo a
getFoo "five" = fiveFoo
getFoo "false" = falseFoo
Run Code Online (Sandbox Code Playgroud)

这里 …

polymorphism haskell existential-type gadt

4
推荐指数
1
解决办法
479
查看次数

在Haskell中使用类型的冒险:GADT:为什么以下的类型检查?

我正在接受Simon Peyton-Jones关于GADT的讲座.在那里,声明了以下数据类型:

data T a where
  T0 :: Bool -> T Bool
  T1 :: T a
Run Code Online (Sandbox Code Playgroud)

然后问的问题是以下函数的类型是什么:

f x y = case x of
          T0 _ -> True
          T1   -> y
Run Code Online (Sandbox Code Playgroud)

对我来说,似乎唯一可能的类型是:

f :: T a -> Bool -> Bool
Run Code Online (Sandbox Code Playgroud)

但是,以下类型:

f :: T a -> a -> a
Run Code Online (Sandbox Code Playgroud)

也有效!确实你可以使用f如下:

 f (T1) "hello"
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么第二类签名f有效?

haskell functional-programming type-inference gadt

4
推荐指数
1
解决办法
176
查看次数

有人可以解释这个OCaml程序中使用的类型语法吗?

以下类型取自此问题

(* contains an error, later fixed by the OP *)
type _ task =
| Success : 'a -> 'a task
| Fail : 'a -> 'a task
| Binding : (('a task -> unit) -> unit) -> 'a task
| AndThen : ('a -> 'b task) * 'a task -> 'b task
| OnError : ('a -> 'b task) * 'a task -> 'b task

type _ stack =
| NoStack : 'a stack
| AndThenStack : …
Run Code Online (Sandbox Code Playgroud)

polymorphism ocaml variant gadt

4
推荐指数
1
解决办法
242
查看次数

将域建模为GADT类型并为其提供do-sugar

假设我们想要构建一个表示典型操作的类型,比如说,一个无锁算法:

newtype IntPtr = IntPtr { ptr :: Int } deriving (Eq, Ord, Show)

data Op r where 
  OpRead :: IntPtr -> Op Int
  OpWrite :: IntPtr -> Int -> Op ()

  OpCAS :: IntPtr -> Int -> Int -> Op Bool
Run Code Online (Sandbox Code Playgroud)

理想情况下,我们希望使用方便do注释在此模型中表示一些算法,例如(假设相应read = OpReadcas = OpCAS出于美学原因)维基百科示例的以下几乎字面翻译:

import Prelude hiding (read)
import Control.Monad.Loops

add :: IntPtr -> Int -> Op Int
add p a = snd <$> do
  iterateUntil fst $ do …
Run Code Online (Sandbox Code Playgroud)

haskell gadt

4
推荐指数
1
解决办法
101
查看次数