我想仅使用此类型定义来定义列表:
data Unit = Unit
data Prod a b = P a b
data Sum a b = L a | R b
newtype Mu f = Mu (forall a . (f a -> a) -> a)
我成功地定义了自然数如下:
zeroMu = Mu $ \f -> f $ L Unit
succMu (Mu g) = Mu $ \f -> f $ R $ g f
我知道如何借助额外的数据类型定义列表:
data ListF a x = NilF | ConsF a x
nilMu' = Mu $ \f -> f $ NilF
consMu' x (Mu g) = Mu $ \f -> f $ ConsF x $ g f
我能得到的'更好'就是这个,但它不是类型检查(预期类型是μL。(1+(a * L))):
nilMu = Mu $ \f -> f $ L Unit
consMu x (Mu g) = Mu $ \f -> f $ R $ P x $ g f
如何仅使用以前定义的类型及其构造函数来定义nilMu
和consMu
?
修改
正如@chi回答所解释的那样,可以按如下方式定义newtype
:
newtype F a x = F (Sum Unit (Prod a x))
nilMu = Mu $ \f -> f $ F $ L Unit
consMu x (Mu g) = Mu $ \f -> f $ F $ R $ P x $ g f
进行类型检查,但需要定义新类型。
这个问题的目的是扩展一个简单类型的组合逻辑,包括单位,乘积,求和和递归类型。前三种类型可以直接实现引入7个新组合器(unit
,pair
,first
,second
,left
,right
,{{ 1}})。递归类型似乎也很容易实现,只需添加一个类型构造函数组合case
,但是这个questoins显示的不够灵活,没有其他语言结构。
这个问题有解决方法吗?是否存在具有递归类型的组合逻辑来进行咨询?
答案 0 :(得分:5)
在Haskell中,如果没有额外的http://some-app-deployed-on.elasticbeanstalk.com/v1/endpoint/${param}
或data
,则无法执行此操作。
要做到这一点,需要编写
newtype
但Haskell不允许以这种方式使用类型级函数。 nilMu :: Mu (\l -> S (P a l) ())
consMu :: a -> Mu (\l -> S (P a l) ()) -> Mu (\l -> S (P a l) ())
只能应用于Mu
种类型的构造函数,而不能应用于同类型的类型函数。
* -> *
其中nilMu :: Mu (F a)
consMu :: a -> Mu (F a) -> Mu (F a)
被定义为附加类型
F a
由于Haskell不允许类型级别函数的原因,请考虑
newtype F a x = F (S (P a x) ())
有人可能会说assuming foo :: f a -> f Char
infer foo True :: ???
,foo True
是True
,因此我们可以推断Bool
和f = \t->t
。结果是a = Bool
。
有人可能会说我们可以推断foo True :: (\t->t) Char = Char
和f = \t->Bool
,结果是a = String
一般来说,我们不喜欢这样。我们希望类型推断通过模式匹配foo True :: (\t->Bool) Char = Bool
和f
来实现。为此,我们希望a
和f
都有一个对应的"显而易见的"实际类型中的名称。
对于它的价值,可以以依赖类型语言(例如Coq,Agda,Idris等)执行此操作。在那里,类型推断不适用于像a
这样的代码以上,因为foo True
无法推断。更糟糕的是,在这些语言中,如果f
并且我们调用bar :: f a -> ...
,那么bar [True]
可能无法推断为f
,因为这不是唯一的解决方案(它们确实有好处)但是,启发式算法,即使一般问题是不可判定的,但通常也会起作用。)