【发布时间】:2016-09-08 16:37:09
【问题描述】:
我的目标是从术语中删除(),如下所示:
(a, b) -> (a, b)
((), b) -> b
(a, ((), b)) -> (a, b)
...
这是代码:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Simplify where
import Data.Type.Bool
import Data.Type.Equality
type family Simplify x where
Simplify (op () x) = Simplify x
Simplify (op x ()) = Simplify x
Simplify (op x y) = If (x == Simplify x && y == Simplify y)
(op x y)
(Simplify (op (Simplify x) (Simplify y)))
Simplify x = x
但是,尝试一下:
:kind! Simplify (String, Int)
...导致类型检查器中的无限循环。我在想If 类型家族应该处理不可约的条款,但我显然遗漏了一些东西。但是什么?
【问题讨论】:
-
您似乎假设类型级计算是惰性的,因此除非需要,否则不会评估
If的第二个分支。我认为这种假设是没有根据的。 -
顺便说一句:在
op上进行多态可能是错误的。例如,Simplify (Either () Int)可能不应该简化为Int。 -
(String, (), Int)上的行为应该是什么?到目前为止,建议的两种解决方案都将其减少到Int。不知道能不能得到(String, Int)。 -
@gallais:没关系,术语只能是(嵌套)元组。
标签: haskell infinite-loop typechecking type-families