[英]Could not match polymorphic type in haskell
我不确定为什么下面的k4
不起作用,而当k3
起作用时,为什么它的多态性足够。 ghci
的错误是
• Couldn't match type 'K' a0 a0' with 'End K'' Expected type: K' a0 a0 -> K'' aa
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
#!/usr/bin/env stack
-- stack --install-ghc --resolver lts-8.21 runghc --package http-conduit --package lens
{-# LANGUAGE ExistentialQuantification, RankNTypes #-}
module YonedaLan where
type End g = forall a. g a a
data K' b c = K'
data K'' b c = K''
k1 :: () -> End K'
k1 x = K'
k2 :: End K' -> End K''
k2 x = case x of (K') -> K''
k3 :: () -> End K''
k3 x = k2 ( k1 x)
k4 :: () -> End K''
k4 = k2 . k1
除了不写自由的风格外,还有一些最佳实践来解决这个问题吗?
问题在于,GHC类型系统永远不会将类型变量实例化为多态类型。 这样做将需要类型系统中的难以置信。
在您的具体示例中,我们有
(.) :: (b->c) -> (a->b) -> (a->c)
然后键入check k2 . k1
k2 . k1
我们需要实例化b ~ End K'
,这是一个多态类型。
一个典型的解决方法是使End K'
成为包裹多态类型的单态类型。 例如
newtype End g = End { unEnd :: forall a. g a a }
付出的代价是在每次使用时明确包装/拆开End g
类型的值。 利用GHC的“安全胁迫”也可以缓解这种情况。
注意,其他一些语言(例如Agda,Coq,Idris)可以很好地处理您的代码(适当翻译),因为它们具有强制性类型系统。 但是,他们的推理机制与Haskell不同-难以置信使它变得更加困难。 有时(如果不是经常的话),类型推断引擎找不到隐式类型参数,必须显式提供类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.