2

我正在尝试实现一个简单的案例,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 的推理规则,因此任何关于该主题的指针也会受到赞赏。

4

1 回答 1

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)

于 2015-07-20T20:10:58.243 回答