标签: undecidable-instances

为什么这段代码使用UndecidableInstances编译,然后生成运行时无限循环?

在使用UndecidableInstances之前编写的代码时,我遇到了一些我发现很奇怪的东西.我设法无意中创建了一些代码,当我认为不应该这样做时:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}

data Foo = Foo

class ConvertFoo a b where
  convertFoo :: a -> b

instance (ConvertFoo a Foo, ConvertFoo Foo b) => ConvertFoo a b where
  convertFoo = convertFoo . (convertFoo :: a -> Foo)

evil :: Int -> String
evil = convertFoo
Run Code Online (Sandbox Code Playgroud)

具体来说,convertFoo函数类型检查在给出任何输入以产生任何输出时,如evil函数所示.起初,我认为也许我设法意外地实现了unsafeCoerce,但事实并非如此:实际上尝试调用我的convertFoo函数(evil 3例如通过执行某些操作)只是进入无限循环.

有点 …

haskell typeclass undecidable-instances

26
推荐指数
2
解决办法
244
查看次数

uncidable实例如何实际挂起编译器?

当我第一次阅读严肃的批评时-XUndecidableInstances,我已经完全习惯了它,将其视为仅仅删除了令人讨厌的限制Haskell98必须使编译器更容易实现.

事实上,我遇到了大量需要不可判定实例的应用程序,但没有一处它们实际上导致任何与不可判定性相关的问题.卢克的例子存在问题,原因完全不同

class Group g where
  (%) :: g -> g -> g
  ...
instance Num g => Group g where
  ...
Run Code Online (Sandbox Code Playgroud)

- 好吧,这显然会被任何适当的实例重叠Group,所以不可判断性是我们最不担心的事情:这实际上是不确定的!

但公平地说,我自己保留了"不可判断的实例可能会让编译器挂起".

当我在CodeGolf.SE上阅读这个挑战时获得它,请求代码无限地挂起编译器.嗯,听起来像是不可判断的实例的工作,对吧?

事实证明我无法让他们这样做.以下编译,至少从GHC-7.10开始:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y
instance C y => C y
main = return ()
Run Code Online (Sandbox Code Playgroud)

我甚至可以使用类方法,它们只会在运行时引起循环:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y where y::y
instance C y => C y …
Run Code Online (Sandbox Code Playgroud)

haskell halting-problem typeclass undecidable-instances

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

在这个例子中它能够避免 UndecidableInstances 吗?

我正在尝试将二叉树实现为类型类:

\n
class BinaryTree bt where\n    empty :: bt a -> Bool\n    empty = isNothing . root\n    emptyTree :: bt a\n    branch :: a -> bt a -> bt a -> bt a \n    root :: bt a -> Maybe a\n    lbranch :: bt a -> bt a \n    rbranch :: bt a -> bt a \n
Run Code Online (Sandbox Code Playgroud)\n

我想用这个定义来说明二叉树是数据容器:

\n
instance BinaryTree bt => Functor bt where\n    fmap f bt = case root bt of\n        Nothing -> emptyTree\n        Just a …
Run Code Online (Sandbox Code Playgroud)

haskell undecidable-instances

2
推荐指数
1
解决办法
103
查看次数

由于UndecidableSuperClasses,GHC陷入困境 - 预期的行为或错误?

以下片段使GHC(在8.6.2和8.4.4中检查)在编译期间卡住:

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE UndecidableSuperClasses #-}

import GHC.Exts (Constraint)

data T = T

type family F t (c :: * -> Constraint) :: Constraint
type instance F T c = c T

class F t C => C t where

t :: C T => t
t = undefined
Run Code Online (Sandbox Code Playgroud)

我认为它会被卡住,因为tGHC试图找到C T,这会导致F T C通过类型族扩展F回来C T,这就是它所寻求的(无限循环).

我认为从理论上说,GHC可以告诉它它自己的追求C T,任何依赖自身的东西都可以递归地工作,或者我误解了什么?

附注:在我偶然发现了这种行为,我能够实现我想要的东西,而不通过更换堵塞在编译器的真实的例子 …

haskell typeclass type-families constraint-kinds undecidable-instances

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