2017-12-17 32 views
1

DuplicateRecordFields (+ OverloadedLabels) 확장 프로그램을 사용하고 있으며 레코드 업데이트에서 명확하게 구분할 수없는 상황이 발생했습니다. 이 일을 할 수있는 방법이DuplicateRecordFields로 레코드 업데이트를 명확히합니다.

data A = A { name :: String } 
data B = B { name :: String } 

combine :: A -> B -> A 
combine a b = a { name = name b } 

있습니까 : 여기

은 간단한 예입니다?

답변

1

당신은 패턴에서 이름과 일치 수 :

data A = A { name :: String } 
data B = B { name :: String } 

combine :: A -> B -> A 
combine a B{name = nb} = a { name = nb } 

그래도 난 DuplicateRecordFields의 팬이 아니에요. 왜 대신 the lens route 가야합니까?

{-# LANGUAGE TemplateHaskell, FlexibleInstances, FunctionalDependencies #-} 

import Control.Lens 
import Control.Lens.TH 

data A = A { _aName :: String } 
makeFields ''A 
data B = B { _bName :: String } 
makeFields ''B 

combine :: A -> B -> A 
combine a b = a & name .~ b^.name 
+0

'-XNamedFieldPuns'으로'B {name} = a {name = name}'을 조합 할 수도 있습니다. – danidiaz

+0

@danidiaz _can_ 이렇게 할 수 있습니까? 네가 그렇게 말하면 어쨌든 우리는 할 수 없다. '{name = name}'은 완전히 혼란스럽게 보입니다. 이러한 모든 확장은 오래된 레코드 시스템 내에서 이러한 방식으로 잘 작동하지 않는 고유 한 해킹입니다. 'OverloadedRecordFields'가'HasField' 클래스와 magic-hash 구문을 통해 정상적으로 작동 할 때, 다른 신발 한쌍이 될 것입니다. 그러나 그때까지는 렌즈 라이브러리가 제공해야하는 것에 충실 할 것입니다. – leftaroundabout

2

나는 현재 GHC는 인수에서 레코드 필드의 유형을 추론하지 않습니다 -XDuplicateRecordFields에 대한 이전 질문 중 하나에 대답

당신은 지금 할 수있는 일 다음과 같이 name 추출기 유형을 명시 적으로 지정하는 것입니다.

{-# LANGUAGE DuplicateRecordFields #-} 

data A = A { name :: String } 
data B = B { name :: String } 

combine :: A -> B -> A 
combine a b = a { name = (name :: B -> String) b }