标签: functional-dependencies

通过利用多个类型类实例之间的对称来缩短代码

上下文

我正在编写一个代表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)

haskell typeclass functional-dependencies template-haskell

9
推荐指数
1
解决办法
329
查看次数

从给定的关系中查找候选键

我一直在研究这个问题,似乎无法找到答案.

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中派生出来的?

提前感谢你.

functional-dependencies candidate-key

9
推荐指数
1
解决办法
1万
查看次数

具有功能依赖性的“实例中的非法类型同义词族应用程序”

我有一个具有功能依赖项的多参数类型类:

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中的疏忽大意吗?

haskell type-families functional-dependencies

9
推荐指数
1
解决办法
806
查看次数

Haskell中的功能依赖

我真的不明白.为什么我们需要呢?我的意思是如果我使用相同的类型参数,我认为这意味着它们应该是相同的类型.

我听说它可以帮助编译器避免无限循环.有人可以告诉我一些更多细节吗?

最后,在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

8
推荐指数
1
解决办法
1295
查看次数

什么是"覆盖条件"?

Statemtl中变压器的来源说明:

-- ---------------------------------------------------------------------------
-- 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有关.

haskell functional-dependencies

8
推荐指数
1
解决办法
536
查看次数

在3NF中找到关系但在BCNF中找不到关系

我一直在阅读许多关于如何区分3NF/BCNF关系的不同来源.到目前为止,这是我的理解......

我将以此关系为例......

R = {A, B, C, D, E}

F = {A -> B, B C - > E, E D -> A}.

首先,我们必须找到关系的关键.我用这个视频来帮助我做到这一点.我得到了

Keys = {ACD, BCD, CDE}

现在要确保RBCNF中,我们必须确保每个功能依赖的左侧F是其中之一Keys.我们立即知道情况并非如此,因为第一个FD是A -> B并且A不是其中一个键.所以它不在BCNF.

现在要确保R3NF中,我们必须确保每个函数依赖的左侧FKeys OR中的每个函数依赖的右侧之一F是其中一个的子集Keys.如果你看看每个FD的右侧,它们就是B,EA.这些都是a的子集Key,因此这意味着它在3NF中.

因此,这是一种罕见的情况(根据维基),其中存在关系3NF存在 …

database 3nf database-normalization functional-dependencies bcnf

8
推荐指数
1
解决办法
1万
查看次数

为什么扩展定义时我的功能依赖冲突会消失?

我试图在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)

haskell ghc functional-dependencies type-level-computation

8
推荐指数
1
解决办法
238
查看次数

相互递归类型的最终无标记编码

我试图在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)

haskell typeclass functional-dependencies

7
推荐指数
1
解决办法
221
查看次数

功能依赖包装在新类型中

我想知道为什么下面的代码不能编译以及是否有mkYValGHC 可以接受的实现。

\n
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\n
Run Code Online (Sandbox Code Playgroud)\n

我也尝试过

\n
mkYVal :: (y  ~ y1, C x y1) => y -> YVal x\nmkYVal y = YVal y\n
Run 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)

haskell typeclass functional-dependencies

7
推荐指数
0
解决办法
80
查看次数

在 GADT 中绑定时,函数依赖不统一

在下面的代码中:

\n
class 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\n
Run Code Online (Sandbox Code Playgroud)\n

根据常识,这应该可行,因为aGADT 和函数中的约束是相同的,并且它确定b,但是这不会编译并出现以下错误:

\n
    \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)

haskell typeclass functional-dependencies gadt

7
推荐指数
1
解决办法
193
查看次数