实现HFoldr时键入类

时间:2015-07-18 19:31:36

标签: haskell hlist

我正在尝试实施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的推理规则,所以关于该主题的任何指针都会受到赞赏。

1 个答案:

答案 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)