2017-11-04 3 views
1

나는 esqueleto을 사용하여 SQL 쿼리를 작성하고 있으며 (Value a, Value b, Value c) 유형의 데이터를 반환하는 쿼리가 하나 있습니다. 그것으로부터 (a, b, c)을 추출하고 싶습니다.(값 a, 값 b, 값 c)에서 추출 (a, b, c)

let (Value a, Value b, Value c) = queryResult 

하지만 모든 튜플 요소에 대한 Value를 반복하지 않도록하고 싶습니다 : 나는 그런 일치하는 패턴을 사용할 수 있다는 것을 알고. 튜플이 훨씬 더 많은 요소 (예 : 10)를 가지고있을 때 이것은 특히 성가시다. 이것을 단순화 할 수있는 방법이 있습니까?

let (a, b, c) = someFunction queryResult 
+0

렌즈 사용을 시도해 보셨습니까? – Redu

+3

Hackage 또는 해당 Github 링크에서 esqueleto 버전을 사용하고 있습니까?Github에서 'Value'는 'newtype'이지만 Hackage는 'data'로 표시됩니다. Github (Gitub)을 newtype으로 사용한다면'someFunction'은'Data.Coerce'의'coerce' 일뿐입니다. 런타임 비용이 전혀 들지 않는다는 이점이 있습니다. –

답변

1

Data.CoercebasesomeFunction의 역할을하는 coerce을 제공합니다.

coerce "교환"newtype은 감싸는 기본 유형 (및 그 반대)입니다. 이것들이 다른 타입 안에 깊게 싸여 있어도 작동합니다. newtype은 랩핑하는 유형과 정확히 같은 런타임 표현을 가지고 있기 때문에 이것은 또한 오버 헤드없이 수행됩니다.

흥미있는 경우 the Wiki page에 대해 읽을 수있는 유형 변수 역할이 좀 더 복잡하지만 패키지가 Value '에 대해'기본 '역할을 사용하므로이 같은 애플리케이션은 간단합니다. s 유형 변수 인수.

2

라이브러리는 unValue 기능을 가지고 나타납니다, 당신은 그냥 임의의 길이의 튜플을 통해지도 할 수있는 방법을 선택해야하므로 : 그처럼 사용할 수있는 기능이있다. Haskell: how to map a tuple?

편집 : 당신이 렌즈 의존하지 않고 튜플을 매핑하는 다른 방법을 시도 할 경우 SomeFunction을 당신이 질문을 확인 할 수,

import Control.Lens (over, each) 

someFunction = (over each) unValue 

가 될 수 danidiaz은 튜플이 단지 작품을 지적 하듯이 최대 8 개의 필드가 있습니다. 나는 그것을 일반화하는 더 좋은 방법이 있는지 확신하지 못한다.

+1

'each'는 크기가 10보다 작은 균질 튜플에서만 작동합니다. – danidiaz

+0

@danidiaz 아, 그게 고통입니다. 내가 생각하기에 링크 된 페이지는 10이라고 했으므로이 사용 사례에 꼭 맞을 것으로 기대하고있었습니다. – Zpalmtree

+1

또한, 여기에 * 균질 * 중요합니다, 나는 그것이 dealbreaker라고 생각합니다. – luqui

2

당신의 튜플은 모두 같은 요소 유형이있는 경우 : @ Zpalmtree의 대답에 설명 된대로

all3 :: (a -> b) -> (a, a, a) -> (b, b, b) 
all3 f (x, y, z) = (f x, f y, f z) 

이 사건은 over each을 사용하여 렌즈를 통해 추상화 될 수 있습니다.

하지만 당신의 튜플은 서로 다른 요소 유형이있는 경우, 당신은 RankNTypes 확장하여이 기능 다형성의 f 인수를 할 수 있습니다 : 당신이 unValue :: Value a -> a이 가정 다음

all3 :: (forall a. c a -> a) -> (c x, c y, c z) -> (x, y, z) 
all3 f (x, y, z) = (f x, f y, f z) 

을, 당신은 쓸 수 있습니다 :

(a, b, c) = all3 unValue queryResult 

그러나 큰 튜플을 가지고 있다면 all4, all5, ..., all10과 같은 별도의 함수를 작성해야합니다. 이 경우 템플릿 하스켈을 사용하여 상용구를 작성하면됩니다. 이것은 하스켈에서 큰 튜플을 피하는 이유 중 하나입니다. 왜냐하면 하스켈은 작업하기에 어색하기 때문에 쉽게 추상화 될 수 없기 때문입니다.