我正在尝试实现一个简单的案例,HFoldr
您将 anEndo a
应用于a
. HList
代码如下所示:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module Lib
( x2, z3
) where
import Data.HList
import Data.Monoid
x2 :: HList '[Sum Integer, String, Sum Integer, String]
x2 = 3 .*. "Hello" .*. 4 .*. " World" .*. HNil
data HUpdateFirst = HUpdateFirst
instance (HOccursNot a l, r ~ (HList l)) => HFoldr HUpdateFirst (Endo a) l r where
hFoldr _ _ l = l
instance (r ~ (HList (a ': l))) => HFoldr HUpdateFirst (Endo a) (a ': l) r where
hFoldr _ f (HCons v l) = HCons (appEndo f v) l
instance (HOccurs a (HList l), r ~ (HList (b ': l)), HFoldr HUpdateFirst (Endo a) l (HList l))
=> HFoldr HUpdateFirst (Endo a) (b ': l) r where
hFoldr h f (HCons v l) = HCons v (hFoldr h f l)
z3 :: HList '[Sum Integer, String, Sum Integer, String]
z3 = hFoldr HUpdateFirst (Endo (++ " X ")) x2
如果我 exclude z3
,代码会编译,但是当我实际z3
输入时,我得到
No instance for (Fail (TypeFound [Char]))
arising from a use of ‘hFoldr’
In the expression: hFoldr HUpdateFirst (Endo (++ " X ")) x2
In an equation for ‘z3’:
z3 = hFoldr HUpdateFirst (Endo (++ " X ")) x2
据我所知,这是说如果不在列表中,它无法弄清楚该怎么做String
,但是a)它是并且b)这就是第一个子句的目的。
我怀疑我的问题可能在于没有更好地理解 Haskell 的推理规则,因此任何关于该主题的指针也会受到赞赏。