首页 文章

在HLists中修复类型推断

提问于
浏览
3

我've been trying to get the some code to compile. It' s意味着采取 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

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

1 回答

  • 2

    ApplyAB 类没有功能依赖,因此当GHC尝试选择实例时,输入类型不会确定结果类型 . 在这种情况下,这会导致 hFoldr 链中的所有中间类型变得不明确,并且GHC不知道要选择哪些实例 .

    要解决这个问题,你可以使用一个技巧,你可以将结果类型保持在实例的头部,并在GHC选择实例后使用等式 ~ 约束来限制它(只有实例的头部用于选择) .

    如果在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
    

相关问题