是否可以从fundep类创建类型族实例?例如,假设我有课
\n\nclass A a b | a -> b\nRun Code Online (Sandbox Code Playgroud)\n\n有一些实例(导入外部库)并希望为该类型系列创建所有相应的实例
\n\ntype family A' a :: *\nRun Code Online (Sandbox Code Playgroud)\n\n这样A' a ~ biff A a b,无需从外部源手动复制和修改实例。
我该怎么做(如果可能的话)?
\n\n迄今为止我最有希望的尝试,
\n\nclass A' a where\n type A'_b a :: *\n\ninstance forall a b. A a b => A' a where\n type A'_b a = b\nRun Code Online (Sandbox Code Playgroud)\n\n给出错误消息
\n\n The RHS of an associated type declaration mentions \xe2\x80\x98b\xe2\x80\x99\n All such variables must be bound on the …Run Code Online (Sandbox Code Playgroud) 我目前正在为一个大学项目工作,现在我对功能依赖项部分有点困惑.对于这个项目,我必须根据自己的项目规范创建逻辑数据模型,并确定功能依赖性.
例如,我给'User'表提供了以下属性.
R(user_id,用户名,regDate,类型,订阅)
主键: user_id
唯一键: username
外键:订阅
示例数据集可能类似于:
1,JohnS,01-01-2012,管理员,NULL
2,PeterB,02-01-2012,版主,电影
3,PeterA,02-01-2012,用户,电影
4,加里,03-01-2012,用户,Books
5,Irene,03-01-2012,用户,电影
6,Stan,03-01-2012,用户,电影
7,Isaac,04-01-2012,用户,书籍
我不明白的部分是我如何确定功能依赖性.我最初的感觉是有两个功能依赖,它们是:
user_id - > username,regDate,type,subscription
username - > user_id,regDate,type,subscription
但是,看一下演讲幻灯片中的其他例子,我怀疑这是否正确.
我想为Data.Map创建一个特殊的智能构造函数,对键/值对关系的类型有一定的约束.这是我试图表达的约束:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, DataKinds #-}
data Field = Speed | Name | ID
data Value = VFloat Float | VString ByteString | VInt Int
class Pair f b | f -> b where
toPair :: f -> b -> (f, b)
toPair = (,)
instance Pair Speed (VFloat f)
instance Pair ID (VInt i)
Run Code Online (Sandbox Code Playgroud)
对于每个字段,只应该与其关联的一种类型的值.就我而言,一个Speed字段映射到一个字段是没有意义的ByteString.一个Speed字段应该唯一映射到一个Float
但是我收到以下类型错误:
Kind mis-match
The first argument of `Pair' should have kind `*',
but `VInt' has kind …Run Code Online (Sandbox Code Playgroud) haskell compile-time type-constraints functional-dependencies gadt
玩弄类型类我想出了看似无辜的人
class Pair p a | p -> a where
one :: p -> a
two :: p -> a
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好,例如
instance Pair [a] a where
one [x,_] = x
two [_,y] = y
Run Code Online (Sandbox Code Playgroud)
但是我为元组遇到了麻烦.即使以下定义编译......
instance Pair (a,a) a where
one p = fst p
two p = snd p
Run Code Online (Sandbox Code Playgroud)
......我无法按预期使用它:
main = print $ two (3, 4)
No instance for (Pair (t, t1) a)
arising from a use of `two' at src\Main.hs:593:15-23
Possible fix: add an instance declaration for …Run Code Online (Sandbox Code Playgroud) 假设我在数据库上有两个表,T 10和T 11,分别有10和11列,其中10列在两者上完全相同.
我违反了什么(如果有的话)规范化规则?
relational-database 3nf database-normalization functional-dependencies
在这里我发现了这个:
定义:数据库表中的决定因素是可用于确定分配给同一行中其他属性的值的任何属性.
示例:考虑具有employee_id,first_name,last_name和date_of_birth属性的表.在这种情况下,字段employee_id确定剩余的三个字段.名称字段不确定employee_id,因为公司可能有多个具有相同名字和/或姓氏的员工.同样,DOB字段不确定employee_id或名称字段,因为多个员工可能共享同一个生日.
候选键的定义是否也适用?
给定一些类型定义:
data A
data B (f :: * -> *)
data X (k :: *)
Run Code Online (Sandbox Code Playgroud)
...和这个类型类:
class C k a | k -> a
Run Code Online (Sandbox Code Playgroud)
...这些(为了最小的例子的目的而高度设计)函数定义类型检查:
f :: forall f. (forall k. (C k (B f)) => f k) -> A
f _ = undefined
g :: (forall k. (C k (B X)) => X k) -> A
g = f
Run Code Online (Sandbox Code Playgroud)
但是,如果我们使用类型族而不是具有函数依赖性的类:
type family F (k :: *)
Run Code Online (Sandbox Code Playgroud)
...然后等效的函数定义无法进行类型检查:
f :: forall f. (forall k. (F k ~ B f) => …Run Code Online (Sandbox Code Playgroud) 关于串联的一个很好的真实事实是,如果我知道等式中的任何两个变量:
a ++ b = c
Run Code Online (Sandbox Code Playgroud)
然后我知道第三个。
我想在我自己的 concat 中捕捉这个想法,所以我使用了函数依赖。
{-# Language DataKinds, GADTs, FlexibleContexts, FlexibleInstances, FunctionalDependencies, KindSignatures, PolyKinds, TypeOperators, UndecidableInstances #-}
import Data.Kind (Type)
class Concatable
(m :: k -> Type)
(as :: k)
(bs :: k)
(cs :: k)
| as bs -> cs
, as cs -> bs
, bs cs -> as
where
concat' :: m as -> m bs -> m cs
Run Code Online (Sandbox Code Playgroud)
现在我像这样召唤异类列表:
data HList ( as :: [ Type ] ) where
HEmpty :: …Run Code Online (Sandbox Code Playgroud) haskell typeclass functional-dependencies type-level-computation
我正在编写一个代表SI前缀的Haskell模块:
module Unit.SI.Prefix where
Run Code Online (Sandbox Code Playgroud)
每个SI前缀都有相应的数据类型:
data Kilo = Kilo deriving Show
data Mega = Mega deriving Show
data Giga = Giga deriving Show
data Tera = Tera deriving Show
-- remaining prefixes omitted for brevity
Run Code Online (Sandbox Code Playgroud)
我想编写一个函数,当应用两个SI前缀时,静态确定两个前缀中的哪一个更小.例如:
-- should compile:
test1 = let Kilo = smaller Kilo Giga in ()
test2 = let Kilo = smaller Giga Kilo in ()
-- should fail to compile:
test3 = let Giga = smaller Kilo Giga in () …Run Code Online (Sandbox Code Playgroud) 我有一个具有功能依赖项的多参数类型类:
class Multi a b | a -> b
Run Code Online (Sandbox Code Playgroud)
我还有一个简单的非内射型同义词家族:
type family Fam a
Run Code Online (Sandbox Code Playgroud)
我想编写一个在第二个参数Multi中使用的实例Fam,如下所示:
instance Multi (Maybe a) (Fam a)
Run Code Online (Sandbox Code Playgroud)
但是,不接受此实例。GHC抱怨以下错误消息:
error:
• Illegal type synonym family application in instance: Fam a
• In the instance declaration for ‘Multi (Maybe a) (Fam a)’
Run Code Online (Sandbox Code Playgroud)
幸运的是,有一种解决方法。我可以执行通常的技巧,将类型移出实例头并移入相等约束:
instance (b ~ Fam a) => Multi (Maybe a) b
Run Code Online (Sandbox Code Playgroud)
该实例被接受!但是,我开始思考,开始怀疑为什么这种转换不能应用于的所有实例Multi。毕竟,功能上的依赖关系是否意味着b每个函数只能有一个a?在这种情况下,GHC似乎没有理由拒绝我的初审。
我发现了GHC Trac故障单#3485,它描述了类似的情况,但是该类型类不涉及功能依赖性,因此(正确地)将故障单视为无效关闭。但是,在我的情况下,我认为功能依赖性避免了故障单中描述的问题。我有什么要忽略的吗?或者这真的是GHC中的疏忽大意吗?