我正在尝试实施HFoldr
,以便将Endo 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
如果我排除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的推理规则,所以关于该主题的任何指针都会受到赞赏。
答案 0 :(得分:0)
答案的极其有限的版本是HOccurs
似乎导致了问题。以下代码有效:
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 a r) = HCons (appEndo f a) r
instance (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)