나는 언어의 흥미있는 가장자리 경우에 여기에서 붙이게되는 것처럼 보인다. 내가 할 노력하고있어 설명, 그래서 내가 대신 코드를 작성할 수 있도록 까다로운 :강제로 유령의 팬텀 타입
data Foobar x =
Foo1 {field1 :: x, field2 :: String} |
Foo2 {field1 :: x, field3 :: Int} |
Foo3 { field4 :: Bool} |
Foo4 { field2 :: String, field4 :: Bool}
당신이 볼 수 있듯이, 일부 생성자 x
에 의존하지만, 다른 사람은하지 않습니다. 나는 fmap
유사한 함수를 작성하려고 해요 : 당신이 볼 수 있듯이
transform :: (x -> y) -> Foobar x -> Foobar y
transform fn foobar =
case foobar of
Foo1 {} -> foobar {field1 = fn (field1 foobar)}
Foo2 {} -> foobar {field1 = fn (field1 foobar)}
_ -> foobar
, 기록 구문은 깔끔하게 내게 필요한 경우에만 fn
을 적용, 전체 생성자를 다시 것을 방지 할 수 있습니다. 불행히도 fn
이 필요하면 에자를 입력해야합니다. 이 경우 (즉, 최종 대안), 표현식은 유형 검사에 실패합니다. 그것은 분명히 내게 확실히 그것은 실패합니다 -하지만 나는 수정 방법에 관해서는 신비 스럽다.
분명히 나는 모든 것을 장시간 쓸 수 있었다. 이것은 잘린 예제를 위해 작동 할 것이지만, 실제로 쓰려는 어플리케이션은 꽤 많이 커집니다. (약 25 명의 생성자, 그 중 일부는 15 개 이상의 필드가 있습니다.)
아무도 내가이 결함을 해결할 수있는 방법에 대한 깔끔한 아이디어가 없습니까?
'파생자 파생 '을 추가하고 컴파일러에서 25 가지 사례를 모두 작성할 수 있습니까? –
@DanielWagner 실제 유형에는 여러 유형 매개 변수가 있습니다. 각 매개 변수에 대해 하나의'transform' 함수를 작성하려고합니다. 나는 그것을 파생시킬 방법을 모른다. – MathematicalOrchid
[이 질문] (http://stackoverflow.com/q/4069840/485115)이 관심의 대상 일 수 있습니다. –