繁体   English   中英

无法匹配Haskell中的多态类型

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM