我正在阅读HList
图书馆的代码。有一个HBetween
类是一个类型级别的函数,它接受一个HNat
n 并返回一个HNat
形成范围 [HZero, n) 的 s 列表。我想实现另一个类HRange
,它有一个重载函数hRange :: l -> u -> r
,它接受一个下限l
和一个上限u
并返回一个范围 [l, u)。我的代码如下(为了使代码更清晰,结果hRange
是相反的,比如 (u, l] )
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
module Data.HList.HNats where
import Data.HList.CommonMain
class (HNat l, HNat u) => HRange l u r | l u -> r where
hRange :: l -> u -> r
instance HNat l => HRange l (HSucc l) (HCons l HNil) where
hRange _ _ = undefined
instance HRange l u r => HRange l (HSucc u) (HCons u r) where
hRange _ _ = undefined
我在 ghci 中尝试了这段代码,发生了一些意想不到的事情:
*Data.HList.HNats Data.HList> :load Data/HList/HNats
[1 of 1] Compiling Data.HList.HNats ( Data/HList/HNats.hs, interpreted )
Ok, modules loaded: Data.HList.HNats.
*Data.HList.HNats Data.HList> hRange hZero (hSucc hZero )
<interactive>:24:1:
Overlapping instances for HRange
HZero (HSucc HZero) (HCons HZero HNil)
arising from a use of `hRange'
Matching instances:
instance HNat l => HRange l (HSucc l) (HCons l HNil)
-- Defined at Data/HList/HNats.hs:14:10
instance HRange l u r => HRange l (HSucc u) (HCons u r)
-- Defined at Data/HList/HNats.hs:20:10
In the expression: hRange hZero (hSucc hZero)
In an equation for `it': it = hRange hZero (hSucc hZero)
*Data.HList.HNats Data.HList>
我不知道为什么hRange hZero (hSucc hZero )
可以匹配 instance instance HRange l u r => HRange l (HSucc u) (HCons u r)
。任何解释表示赞赏!