我正在编写一个代表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) 我一直在研究这个问题,似乎无法找到答案.
R = (A, B, C, D, E)
Run Code Online (Sandbox Code Playgroud)
功能依赖是:
A => B
ED => A
BC => E
Run Code Online (Sandbox Code Playgroud)
然后它将候选键列为:
ACD, BCD, CDE
Run Code Online (Sandbox Code Playgroud)
这些候选密钥是如何从上述FD中获得的?
同样,在哪里R = (A, B, C, D):
功能依赖是:
D => B
AB => D
AB => C
C=> A
Run Code Online (Sandbox Code Playgroud)
然后它将候选键列为:
AB, BC, CD, AD
Run Code Online (Sandbox Code Playgroud)
同样,我的问题是我不确定候选密钥是如何从FD中派生出来的?
提前感谢你.
我有一个具有功能依赖项的多参数类型类:
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中的疏忽大意吗?
我真的不明白.为什么我们需要呢?我的意思是如果我使用相同的类型参数,我认为这意味着它们应该是相同的类型.
我听说它可以帮助编译器避免无限循环.有人可以告诉我一些更多细节吗?
最后,在Real World Haskell中我们应该遵循功能依赖的使用吗?
[后续问题]
class Extract container element where
extract :: container -> element
instance Extract (a,b) a where
extract (x,_) = x
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我对容器和元素都使用了相同的类型变量'a',我认为编译器因此可以推断这两种类型是相同的类型.
但是当我在GHCi中尝试这个代码时,我收到了以下反馈:
*Main> extract('x',3)
<interactive>:1:0:
No instance for (Extract (Char, t) element)
arising from a use of `extract' at <interactive>:1:0-13
Possible fix:
add an instance declaration for (Extract (Char, t) element)
In the expression: extract ('x', 3)
In the definition of `it': it = extract ('x', 3)
Run Code Online (Sandbox Code Playgroud)
当其中一个被指定为类型'Char'时,为什么另一个仍未解析类型'element'?
haskell types type-systems typeclass functional-dependencies
-- ---------------------------------------------------------------------------
-- Instances for other mtl transformers
--
-- All of these instances need UndecidableInstances,
-- because they do not satisfy the coverage condition.
Run Code Online (Sandbox Code Playgroud)
什么是"覆盖条件"?我只能说它与MTPC和fundeps有关.
我一直在阅读许多关于如何区分3NF/BCNF关系的不同来源.到目前为止,这是我的理解......
我将以此关系为例......
R = {A, B, C, D, E}
和
F = {A -> B, B C - > E, E D -> A}.
首先,我们必须找到关系的关键.我用这个视频来帮助我做到这一点.我得到了
Keys = {ACD, BCD, CDE}
现在要确保R在BCNF中,我们必须确保每个功能依赖的左侧F是其中之一Keys.我们立即知道情况并非如此,因为第一个FD是A -> B并且A不是其中一个键.所以它不在BCNF.
现在要确保R在3NF中,我们必须确保每个函数依赖的左侧F是Keys OR中的每个函数依赖的右侧之一F是其中一个的子集Keys.如果你看看每个FD的右侧,它们就是B,E和A.这些都是a的子集Key,因此这意味着它在3NF中.
因此,这是一种罕见的情况(根据维基),其中存在关系3NF但不存在 …
database 3nf database-normalization functional-dependencies bcnf
我试图在Haskell中的类型级别实现Integers.首先,我实现了自然数
data Zero
data Succ a
Run Code Online (Sandbox Code Playgroud)
然后我将其扩展为整数
data NegSucc a
Run Code Online (Sandbox Code Playgroud)
我决定然后创建一个Increment增加整数的类.我是这样做的:
{-# Language FunctionalDependencies #-}
{-# Language UndecidableInstances #-}
{-# Language MultiParamTypeClasses #-}
{-# Language FlexibleInstances #-}
import Prelude ()
-- Peano Naturals --
data Zero
data Succ a
class Peano a
instance Peano Zero
instance (Peano a) => Peano (Succ a)
-- Integers --
data NegSucc a -- `NegSucc a` is -(a+1) so that 0 can only be expressed one way
class Integer a
instance (Peano a) …Run Code Online (Sandbox Code Playgroud) 我试图在final-tagless编码中表达一对相互递归的数据类型.
我能写:
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE ExplicitForAll #-}
module Test where
class ExprSYM repr where
expr :: forall proc. (ProcSYM proc) => proc Int -> repr
class ProcSYM repr where
varProc :: forall a. String -> repr a
intProc :: String -> repr Int
subjectOf :: forall expr. (ExprSYM expr) => expr -> repr Int
myProc = intProc "proc A."
Run Code Online (Sandbox Code Playgroud)
但是,当我写:
myExpr = expr myProc
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
Could not deduce (Test.ProcSYM proc0)
arising from a use of …Run Code Online (Sandbox Code Playgroud) 我想知道为什么下面的代码不能编译以及是否有mkYValGHC 可以接受的实现。
class C x y | x -> y\nnewtype YVal x = YVal { getYVal :: forall y . C x y => y }\nmkYVal :: C x y => y -> YVal x\nmkYVal y = YVal y\nRun Code Online (Sandbox Code Playgroud)\n我也尝试过
\nmkYVal :: (y ~ y1, C x y1) => y -> YVal x\nmkYVal y = YVal y\nRun Code Online (Sandbox Code Playgroud)\n但它仍然说
\n[...]: error:\n \xe2\x80\xa2 Couldn\'t match type \xe2\x80\x98y2\xe2\x80\x99 with \xe2\x80\x98y1\xe2\x80\x99\n \xe2\x80\x98y2\xe2\x80\x99 is a rigid type variable …Run Code Online (Sandbox Code Playgroud) 在下面的代码中:
\nclass FD a b | a -> b\n\ndata Foo a where\n Foo :: FD a b => b -> Foo a\n\nunFoo :: FD a b => Foo a -> b\nunFoo (Foo x) = x\nRun Code Online (Sandbox Code Playgroud)\n根据常识,这应该可行,因为aGADT 和函数中的约束是相同的,并且它确定b,但是这不会编译并出现以下错误:
\xe2\x80\xa2 Couldn't match expected type \xe2\x80\x98b\xe2\x80\x99 with actual type \xe2\x80\x98b1\xe2\x80\x99\n \xe2\x80\x98b1\xe2\x80\x99 is a rigid type variable bound by\n a pattern with constructor:\n Foo :: forall a b. FD a b => b -> Foo a,\n in …Run Code Online (Sandbox Code Playgroud)