2013-05-11 1 views
1

나는 HList 라이브러리의 코드를 읽습니다. HBetween 클래스는 HNat을 취하고 범위를 형성하는 HNat의 목록을 반환하는 유형 수준 함수입니다 [HZero, n). 다른 클래스 HRange을 구현하고 싶습니다. 오버로드 함수 hRange :: l -> u -> r이 있는데, 이는 낮은 경계 인 l과 상한 인 u을 사용하고 [l, u] 범위를 반환합니다. 내 코드는 아래 (코드가 더 명확하게하는 것입니다, hRange의 결과가 반대 순서에, (유, L])haskell의 중복 인스턴스

{-# 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) 일치 수없는 이유

나도 몰라. 어떤 설명이 감사합니다! GHC는 HRange HZero (HSucc HZero) (HCons Zero HNil)hRange hZero (hSucc hZero)의 유형을 준다

답변

3

참고. GHC 인스턴스 정규 고려하지 않기 때문에 제약 조건을 선택하기 전에 HRange l (HSucc u) (HCons u r)을 확인하면됩니다. l은 어떤 것과도 일치 할 수 있으므로 일치하는 내용은 HZero입니다. HSucc uHSucc HZero과 명확하게 일치하며 HCons u rHCons HZero HNil입니다. 일반적

는 멀리 GHC 관한 한, 두번째 인스턴스는 인스턴스를 선택하는 경우에만 우변의 차이 (이에 제한을 무시 HNat lHRange l u r) 이후, 제이며, 제 엄격한 상위 집합 두 번째는 r으로 제한되고 HNil으로 제한됩니다. 이 문제에 대한 일반적인 접근 방식은 팬텀 유형이나 클래스를 던져 오른쪽면을 구별하는 것입니다. 비록 머리 꼭대기에서 벗어나지 만 여기에서 어떻게하는지는 알지 못합니다.

+0

대단히 감사합니다. 나는 다른 방법을 찾고 있습니다. :) – pysuxing