2013-08-27 6 views
1

하스켈 : 같은 쌍의 전문화

--Say I have the following monad: 

{-# LANGUAGE GADTs, FlexibleInstances #-} 

data Instruction b where 
    Write :: a -> Instruction() 
    Write2 :: (a,a) -> Instruction() 
    Read :: Instruction a 
    Read2 :: Instruction (a,a) 
    Bind :: Instruction a -> (a -> Instruction b) -> Instruction b 
    Return :: a -> Instruction a 

instance Monad Instruction where 
    (>>=) = Bind 
    return = Return 

--And the following class: 

class Box a where 
    write :: a -> Instruction() 
    read :: Instruction a 

instance Box Int where 
    write = Write 
    read = Read 

instance Box Float where 
    write = Write 
    read = Read 

instance (Box a,Box b) => Box (a,b) where 
    write (a,b) = do 
    write a 
    write b 
    read = do 
    a <- Read 
    b <- Read 
    return (a,b) 

instance (Box a) => Box (a,a) where 
    write = Write2 
    read = Read2 

--Now, this works kind of fine, as long as I do not use the overlap: 

test = do 
    let i = 0 :: Int 
    let f = 0 :: Float 
    write (i,f) 
    --But i get an overlapping instance for the following (understandably): 
    write (i,i) 

는 "옳은 일"을 할 것입니다 클래스의이 종류를 작성 가능 (쉽게 복사 및 붙여 넣기에 대한 의견을 사용하여)와 한 쌍의 인스턴스 겹치는? 즉, 올바른 인스턴스가 선택되도록 프로그램을 어떻게 변경합니까?

저는 하나의 런타임 솔루션에 대해 알고 있다고 생각하지만, 그렇게 좋지는 않을 것입니다.

내가 다시 작성한 규칙을 보았습니다. 좋은 해결책입니까?

+0

정말 두 번째 인스턴스가 필요합니까? 나는 Box (a, b)가 첫 번째 것보다 다른 두 번째 것을 기대하지 않는다면, Box (a, a)의 좀 더 일반화 된 형태라고 생각할 것이다. – bheklilr

+0

명확하지 않으면''Box (a, a)''는''Write2''와''Read2''를 사용합니다. 이것은 다른 동작입니다. 이것이 질문의 요점입니다. – nulvinge

+0

'OverlappingInstances' 언어 pragma를 사용해 보셨습니까? http://stackoverflow.com/a/1072523/839246과 비슷한 문제가있는 것 같습니다. – bheklilr

답변

3

이 경우 OverlappingInstancespragma를 사용할 수 있습니다. Box (a,a)Box (a,b)보다 구체적이므로 컴파일러는 올바른 인스턴스를 선택합니다.

b에서 a까지 인스턴스화 할 수 있다면 비공식적으로 ab보다 구체적이라고 말하면됩니다. 다른 정의는 ab을 통합하면 a이됩니다. 예를 들어 (a,b)b = a을 입력 할 수 있으므로 (a,a)(a,b)보다 구체적입니다.

컴파일러가 가장 구체적인 인스턴스를 찾을 수 없으면 OverlappingInstances과 함께 오류가 발생합니다.

+0

흥미 롭습니다. 보다 구체적인 기준은 무엇입니까? 이 경우 더 구체적인 인스턴스는보다 일반적인 인스턴스 집합 내에 있습니다. 단순히 겹치면 어떨까요? 어느 인스턴스가 가장 구체적입니까? – nulvinge

+0

@nulvinge http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/type-class-extensions.html – Satvik

+0

@nulvinge 업데이트 된 답변보기. – Satvik