我在Haskell中定义了自己的数据类型来表示单变量多项式。
data Polinomio a where
Pol :: (Num a) => a -> Integer -> Polinomio a -> Polinomio a
Cons :: (Num a) => a -> Polinomio a
我在这里使用了GADT来约束a变量,使其属于Num Class。现在,我想为Functor类定义我自己的实例
instance Functor Polinomio where
fmap f (Cons x) = Cons $ f x
我试图使用DataKinds进行类型级编程,但是当我将这些结构中的一个嵌套在另一个结构中时,就会遇到困难。
{-# LANGUAGE DataKinds, TypeFamilies, GADTs, MultiParamTypeClasses, FlexibleInstances #-}
module Temp where
data Prop1 = D | E
data Lower :: Prop1 -> * where
SubThing1 :: Lower D
SubThing2 :: Lower E
class ClassLower a where
somefun
带有关联数据族X的类型类X需要一个函数coerceX。如果我像下面这样实现了类型分类,我如何编写coerceX
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
import Data.Type.Coercion
import Control.Monad.Reader
data (T r t)
class C t where
data X t :: * -> *
coerceX :: Coercion a b -> C
我正在报道GADT使用learnyouahaskell,我对它们的可能用途感兴趣。我知道他们的主要特点是允许显式的类型设置。
例如:
data Users a where
GetUserName :: Int -> Users String
GetUserId :: String -> Users Int
usersFunction :: Users a -> a
usersFunction (GetUserName id)
| id == 100 = "Bob"
| id == 200 = "Phil&
下面是我真正要问的一般性问题的一个具体例子:假设我处于一个性能关键的代码部分,并且我已经收到了一个值
x :: Maybe Int
我知道这是一个Just Int,而不是一个Nothing,但是由于代码超出了我的控制范围,我无法安排直接接收实际的Int。我想做
case x of
Just i -> whatever i
但我不希望GHC插入任何检查、错误处理或跳转之类的内容,只需将这些位元解释为表单Just i,然后让我来处理其后果。
这个是可能的吗?(是的,我知道这是我们不应该经常做的事情。)
让我说我有这个程序
{-# LANGUAGE GADTs #-}
data My a where
A :: Int -> My Int
B :: Char -> My Char
main :: IO ()
main = do
let x = undefined :: My a
case x of
A v -> print v
-- print x
编译得很好。
但当我在print x上发表评论时,我得到:
gadt.hs: line 13, column 12:
Couldn't match type ‘a0’ with ‘
使用下面的代码
{-# LANGUAGE GADTs #-}
data X a where
X :: (Show a, Num a) => a -> X a
instance Show (X a) where
show (X x) = "X " ++ show x
instance Num (X a) where
fromInteger x = X $ fromInteger x
我得到了这个错误:
No instance for (Show a) arising from a use of `X'
Poss
考虑到这个GADT
type _ t =
| A : (string -> 'ok) * (string -> 'err) -> ('ok, 'err) result t
为什么这与“类型构造函数将转义其作用域”错误一起失败?
let f (type a) (gadt: a t): a Future.t =
Future.bind (fetch ()) (fun response ->
match gadt with
| A (ok, _) -> Ok (ok response))
Error: T
我对Haskell类型系统有一个误解,我认为这种误解可能很常见,但我找不到对这个简单示例显示的特定类型检查失败的解释:
{-#LANGUAGE GADTs, FunctionalDependencies #-}
module GaF where
class XDeterminesY x y | x -> y
instance XDeterminesY Int Double
data Wrapper x where
WrappedInt :: Wrapper Int
func :: XDeterminesY x y => Wrapper x -> y ->
为什么Monoid实例需要(Ord a,Ord b)约束,而半群实例不需要约束?
这取决于Category.Constrained类还是使用GADT来定义数据类型?
{-# LANGUAGE GADTs, TypeFamilies, ConstraintKinds, StandaloneDeriving #-}
module Question3 where
import Control.Category.Constrained as CC
import Data.Set as S
import Data.Map as M
data RelationMS a b where
IdRMS
编辑:,我已经跟进了一个更多的。谢谢各位在此作答,我认为跟进问题更能解释我在此提出的一些混淆问题。
TL;DR I正在努力将约束的证明转化为表达式,同时在构造函数上使用带有存在约束的GADT。(这是一个严肃的嘴,对不起!)
我把一个问题归结到以下几个方面。我有一个简单的GADT,它表示称为X的点和称为F的函数应用程序。点X被限制为Objects。
data GADT ix a where
X :: Object ix a => a -> GADT ix a
F :: (a -> b) -> GADT ix a -> GADT ix b
Constrai
{-# LANGUAGE GADTs #-}
module Main where
data CudaExpr x where
C :: x -> CudaExpr x
Add :: Num x => CudaExpr x -> CudaExpr x -> CudaExpr x
Sub :: Num x => CudaExpr x -> CudaExpr x -> CudaExpr x
Mul :: Num x => CudaExpr x -> CudaExpr x -> CudaExpr x
Div :: (
我用Haskell写了以下线性代数向量
data Natural where
Zero :: Natural
Succ :: Natural -> Natural
data Vector n e where
Nil :: Vector Zero e
(:|) :: (Show e, Num e) => e -> Vector n e -> Vector (Succ n) e
infixr :|
instance Foldable -- ... Vector ..., but how do I implement this?
当我尝试实
让我们想象我有一个存在主义类型T
T = ∃X { a :: X, f :: X -> Int}
其中我创造了一个价值
v :: T
v = pack {Int, { a = 0, f x = 0 } } as T
因此:
此值的用户禁止知道在实现中实际使用的是哪种类型的X。为了使用这个值,他们的代码在X中具有多态的。
另一方面,实现者完全知道X实际上是一个Int,并且可以按他的意愿使用底层类型的容量。
我想知道,这一机制是否有不破坏证据的变体:
w, v = pack {Int, { a = 0, f x = 0 } } as T
s = unpack w v
我有一个类型类型,它强加了一个KnownNat约束:
class KnownNat (Card a) => HasFin a where
type Card a :: Nat
...
而且,对于几个基本的“构建块”类型,我有这个类的实例:
instance HasFin () where
type Card () = 1
...
instance HasFin Bool where
type Card Bool = 2
...
我计划从这些构建块类型中构建许多“复合”类型,使用和产品。目前,当我为其中一种组合类型实例KnownNat时,我不得不显式地编写复合Ha
类似于
data Foo = forall a. MkFoo a (a -> Bool)
| Nil
可以轻松地转换为GADT:
data Foo where
MkFoo :: a -> (a -> Bool) -> Foo
Nil :: Foo
它们之间是否有什么区别:用一个而不是另一个编译的代码,或者给出不同的结果?
我有一个可插拔的运行时类型检查器,它支持参数化,但不支持即席多态,因为没有编译步骤,类型检查器一被禁用就会删除类型信息。
现在,我提出了用显式类型来还原类型类的想法,这样我就可以获得它们的一些优势,而不必将底层机制完全合并到类型检查器中:
data Functor f = Functor {fmap :: forall a b. (a -> b) -> f a -> f b}
mapList = Functor map
fmap (mapList) (+1) [1,2,3]
似乎类型类可以用秩-2类型来模拟,至少在类型级别上是这样的,因为,当然,仍然没有静态调度。
我的假设
聚酰胺型应用是注射型的吗?
当我们时,我们知道f a ~ g b意味着f ~ g和a ~ b吗?
动机
当使用时,我将问题减少到只在启用PolyKinds时才收到以下错误。
Could not deduce (c1 ~ c)
from the context ((a, c z) ~ (c1 a1, c1 b))
如果聚酰胺类应用是注射式的,我们可以推断出c1 ~ c如下。
(a, c z) ~ (c1 a1, c1 b)
(a,) (c z) ~ (c1 a1,) (c1 b) {- switch to prefix notation -}
c z ~
data T a where
T1 :: Bool -> T Bool
T2 :: T a
f x y = case x of
T1 x -> True
T2 -> y
西蒙说f可以输入为T a -> a -> a,但我认为返回值必须是Bool,因为这是case表达式的分支中的一个显式结果。这是关于Haskell GADTs的。为什么是这种情况?
我有以下类型的家庭:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DataKinds #-}
data Nat = Z | S Nat
type family WrapMaybes (n :: Nat) (a :: *) :: *
type instance WrapMaybes Z a = a
type instance WrapMaybes (S n) a = Maybe (WrapMaybes n a)
这在很大程度上如预期的那样工作,例如WrapMaybes (S (S Z)) Int ~ Maybe (Maybe Int)。
现在,很明显(
为这个有点做作的例子道歉。我试图在不失去理由的情况下,尽可能地简化这一点:
假设我有一个多参数类型Relation
class Relation r a b where ....
一种在这种类型上存在量化的函数:
neighbours :: forall r a b. Relation r a b => a -> r -> Graph -> [b]
现在我介绍几个Relation实例
data Person = Person String
data Pet = Pet String
data Owns = Owns
data Desires = Desires
inst
我有一个参数化类型,我想将它限制为一个数值类型,更具体地说,是一个Fractional,例如:
data Rating a = (Fractional a) => Score a | Unscored deriving (Show, Eq)
这样,API的用户就可以定义他们可能使用的非整数类型(Float或Double?),但是我编写的内部API代码仍然可以对数字类型执行算术操作。我不希望它是一个整数,因为我的“内部操作”的结果可能不是整数,我的理解是,使用Fractional将导致更精确的结果。
编译上面的内容(至少在GHCI中)会给出以下错误:
Data constructo
我想用字段sType来表示数据类型,它是SType的任何实例(来自)。SType是zeromq套接字类型。在zeromq-haskell源中,一个例子是:
data Pair = Pair
instance SType Pair where
zmqSocketType = const pair
这是我现在得到的
data SocketOpts = SocketOpts
{ end :: SocketEnd
, sType :: SType st => st
}
但是当我像socket ctx $ sType so一样使用它时,我得到:
Ambiguous type vari
我有以下GADT
data Vec n a where
T :: Vec VZero a
(:.) :: (VNat n) => a -> (Vec n a) -> (Vec (VSucc n) a)
为固定长度的向量建模,使用类
class VNat n
data VZero
instance VNat VZero
data VSucc n
instance (VNat n) => VNat (VSucc n)
我尝试在向量上编写一个append函数:
vAppend :: Vec n b -> Vec m b -> Vec nm
即使没有扩展ExistentialQuantification,Haskell也通过类型同构为任何类型的C支持一些存在类型,
(forall a. C a => (a -> b)) ~ ((exists a. C a => a) -> b)
因此,函数f :: C a => a -> b需要一个类型为exists a. C a的参数x。但是Haskell不允许模式匹配x与某些类型的C (由野生匹配_完成,因为类型类通常是无限的)。
这很奇怪,因为存在型是广义和类型。Haskell使用data关键字支持有限和类型,并允许它们进行模式匹配。在C++、Java
我试图使用一个类型家族来生成依赖于某种类型级别自然数的约束。以下是这样一种功能:
type family F (n :: Nat) (m :: Nat) :: Constraint where
F 0 m = ()
F n m = (m ~ 0)
然后我有一个函数,它有这个约束。
f :: forall n m. (KnownNat n, KnownNat m, m ~ 0) => ()
f = ()
当我试图在模式匹配中使用这个函数时,我的类型家族应该产生这个约束,ghc说它不能推导出约束。
下面是一个示例:
g :: forall n m. (KnownNat n, Know
我有一个类型家族的定义如下:
type family Vec a (n :: Nat) where
Vec a Z = a
Vec a (S n) = (a, Vec a n)
我想断言,应用这个类型家族的结果总是满足来自SBV包的SymVal类约束:
forall a . (SymVal a) => SymVal (Vec a n)
有SymVal实例a,b,所以每当SymVal a保存时,SymVal (Vec a n)就应该保持n的任何值。如何确保GHC看到SymVal总是为类型家族应用程序的结果实现的?
然而,我不知道如何表达这一点。我要写一个实例吗?派生条款?我不是在创
我很难理解为什么这个代码:
-- someNatVal test case
--
-- David Banas <capn.freako@gmail.com>
-- August 5, 2018
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import GHC.TypeLits
import Data.Proxy
tellNat :: forall n. KnownNat
我有以下类型类和实例:
class StatType a where
toDouble :: a -> Double
instance StatType Double where
toDouble = id
instance Integral a => StatType a where
toDouble = fromIntegral
avg :: StatType a => [a] -> Double
avg = undefined
但接下来的表情
*Example> avg ([1,2,3,4] :: [Double])
报告与重叠实例有关的类型错
我正在尝试创建一个数据类型,Point,它的构造函数使用三个数字。一开始,我写了
data Point = Point Double Double Double
但是当某些代码需要Int时,我遇到了一些问题。
所以我把它改成了
data Point a = Point a a a
但是现在我要强制执行a是一个实例(?)Num -我只想接受构造函数中的数字。
这个是可能的吗?如果没有,什么是公认的做法?我用错了多少次来形容某事?
下面的代码不会编译,并给出
无法将类型‘c1’与‘c’‘c1’相匹配,它是一个刚性类型变量,由构造函数: SomeReq ::forall c. Conn c => Req c -> SomeReq,在“run”的等式中绑定。
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ExistentialQuantification #-}
module Main where
import qualified Data.Text as T
class Conn c where
data Auth c :: *
data Env c
我大致想要实现以下几点:
f :: a -> a
g :: b -> b
h :: Typeable t => t -> Maybe t
h x = case x of
(x is of type a) -> Just (f x)
(x is of type b) -> Just (g x)
_ -> Nothing
这三者之间的区别是什么/为什么?GADT (和常规数据类型)仅仅是数据族的缩写吗?具体地说,它们之间的区别是什么:
data GADT a where
MkGADT :: Int -> GADT Int
data family FGADT a
data instance FGADT a where -- note not FGADT Int
MkFGADT :: Int -> FGADT Int
data family DF a
data instance DF Int where -- using GADT sy
亲爱的Haskell/GHC专家:
我真的不明白为什么GHC报告重叠的实例,而根据所提供的上下文,只有一个实例是有效的。例如,让我们考虑以下代码:
{-# LANGUAGE FlexibleInstances #-}
class C a where
foo :: a -> String
foo x = "OK"
instance C Bool
instance (C a) => C [a]
instance (C a) => C [(Char, a)]
main = print $ foo [('a', True)]
汇编
我想了解更多关于幻影类型的知识。我正在读罗尔夫·辛兹的“”。他使用了一个关键字with,这是我以前从未见过的,我无法编译。当我尝试这样做时,我会在=上得到一个解析错误。
data Type t = RInt with t = Int
| RChar with t = Char
| RList (Type a) with t = [a ]
| RPair (Type a) (Type b) with t = (a, b)
在前面的文章
此代码示例不编译。
{-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances, ScopedTypeVariables #-}
module IncoherentBug where
type family F a where
F () = Int
F a = a
class C a where
c :: a -> Int
instance C Int where
c y = y
instance {-# INCOHERENT #-} Monoid a => C a w