无法匹配haskell

时间:2017-08-30 15:18:26

标签: haskell polymorphism

我不确定为什么k4下面的k3不起作用,ghci确实如此,其足够的多态性。 • Couldn't match type ‘K' a0 a0’ with ‘End K'’ Expected type: K' a0 a0 -> K'' a a 中的错误是

{-# 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
Toast.makeText(getApplicationContext(), "Authentication failed!" , Toast.LENGTH_SHORT).show();

除了不写自由风格之外,还有一些最佳实践可以解决这个问题吗?

1 个答案:

答案 0 :(得分:4)

问题是GHC类型系统永远不会将类型变量实例化为多态类型。这样做需要类型系统中的不可靠性。

在你的具体例子中,我们有

(.) :: (b->c) -> (a->b) -> (a->c)

并且,要键入check k2 . k1,我们需要实例化b ~ End K'这是一种多态类型。

典型的解决方法是将End K'转换为包含多态类型的单态类型。 E.g。

newtype End g = End { unEnd :: forall a. g a a }

要付出的代价是在每次使用时明确包装/解包类型End g的值。这也可以通过GHC的安全强制来减轻这种情况。

请注意,其他一些语言(如Agda,Coq,Idris)会很好地处理您的代码(适当翻译),因为它们具有不可预测的类型系统。然而,他们的推理机制与Haskell不同 - 不确定性使其变得更加困难。有时,如果不经常,类型推理引擎无法找到隐式类型参数,并且必须明确提供类型。