HLists中的修复类型推断

我一直试图让一些代码来编译。 它的意思是采取一个HList ,提取出字符串并将它们连接在一起。


{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Lib
    ( y
    ) where

import Data.HList

data HConcat2 = HConcat2
instance ApplyAB HConcat2 (String, String) String where
  applyAB _ (a,b) = a ++ b
instance ApplyAB HConcat2 (Int, String) String where
  applyAB _ (_,a) = a

x :: HList '[Int, String, Int, String]
x = 3 .*. "Hello" .*. 4 .*. " World" .*. HNil

y :: String
y = hFoldr HConcat2 "Result: " x

不幸的是,当我尝试编译它时,它给了我

    No instance for (ApplyAB HConcat2 ([Char], [Char]) r2)
      arising from a use of ‘hFoldr’
    The type variable ‘r2’ is ambiguous
    Note: there is a potential instance available:
      instance ApplyAB HConcat2 (String, String) String
        -- Defined at src/Web/Rusalka/Condition.hs:274:10
    In the expression: hFoldr HConcat2 "Result: " x
    In an equation for ‘y’: y = hFoldr HConcat2 "Result: " x

我如何说服它使用我声明的实例?


ApplyAB类没有函数依赖关系,所以当GHC试图选择一个实例时,输入类型不确定结果类型。 在这种情况下,这会导致hFoldr链中的所有中间类型变得不明确,而GHC不知道要选择哪些实例。

为了解决这个问题,你可以使用一个小技巧,让您保持结果类型的实例的头部完全通用的,并使用一个等式~约束来限制它GHC已经选择后的实例(仅用于实例的头选择)。

如果你这样做:i ApplyAB在GHCi中应用:i ApplyAB ,你会注意到几个预定义的实例使用了这样的等式约束。

使用这个(并添加TypeFamilies )使您的代码适合我:

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}

module Lib
    ( y
    ) where

import Data.HList

data HConcat2 = HConcat2
instance s ~ String => ApplyAB HConcat2 (String, String) s where
  applyAB _ (a,b) = a ++ b
instance s ~ String => ApplyAB HConcat2 (Int, String) s where
  applyAB _ (_,a) = a

x :: HList '[Int, String, Int, String]
x = 3 .*. "Hello" .*. 4 .*. " World" .*. HNil

y :: String
y = hFoldr HConcat2 "Result: " x
链接地址: http://www.djcxy.com/p/43089.html

上一篇: Fixing type inference in HLists

下一篇: Folding over a polymorphic list in Haskell