【发布时间】:2013-05-11 16:05:51
【问题描述】:
我正在阅读HList 库的代码。有一个HBetween 类,它是一个类型级函数,采用HNat n 并返回一个HNats 列表,形成一个范围[HZero,n)。我想实现另一个类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 HRange l u r => HRange l (HSucc u) (HCons u r)。任何解释表示赞赏!
【问题讨论】:
标签: haskell types metaprogramming