술어 함수로 패턴을 사용하는 편리한 방법이 있습니까?


10

최근에 술어 함수를 다른 함수에 전달해야하는 상황이 발생했습니다. 필자가 자주 찾는 논리는 본질적으로 "이 값이이 패턴과 일치합니까?"입니다.

패턴 일치는 선언, do블록 및 목록 이해 에서 선호되는 것처럼 보이지만 술어를 취하는 많은 함수가 있습니다. a -> Bool여기서 패턴을 전달하는 것이 매우 편리합니다. 예를 들어, takeWhile, until, find, span, 등

지금까지 나는 \a -> case a of MyCons _ -> True; otherwise -> False명명 된 함수 a la를 작성 let myPred (MyCons _) = True; myPred _ = False in했지만, 둘 다 아주 추악하고 관용적이지 않은 것처럼 보입니다. "명백한"(그리고 잘못된) 방법은 비슷 \(MyCons _) -> True하지만 부분적이고 자연스럽게 오류를 발생 시키며 심지어 더 깨끗한 방법이 있어야한다고 생각합니다.

이런 종류의 일을하는 간결하고 깨끗한 방법이 있습니까? 아니면 완전히 잘못된 방향으로 가고 있습니까?


1
어쩌면 이것은 "개인 취향"일지도 모르지만, 한 곳 에서이 술어 만 필요하다면 let싫어하는 조항에 매우 만족할 것 where입니다. 물론이 유틸리티가 두 번 이상 필요한 경우에는 최상위 기능으로 정의해야합니다.
로빈 지그 먼드

확실히 잘 작동합니다. 내 질문은 Haskell이 얼마나 간결하게 간결한 지에 따라 다소 동기가 부여되었습니다. 일반적으로 관용적 하스켈은 아이디어의 중복이 거의 없으며 보풀을 최소화합니다. 따라서 let myPred...스타일이 나쁘다고 생각할 필요는 없지만 매우 간단한 아이디어를 기대할 때보 다 훨씬 장황하게 느껴져 잘못된 트리를 짖는 지 궁금해집니다.
David Sampson

2
프리즘을 볼 수 있습니다 (렌즈에서). 그것들은 일류
컴포저 블

1
이 유형의 고차 함수를 사용하는 예를보아야한다고 생각합니다. 저의 일부는 문제가 처음에 그러한 술어를 필요로하는 디자인에 있다고 말하고 싶습니다.
chepner

이를 위해 Haskell98 방식은 maybe :: b -> (a -> b) -> Maybe a -> band와 같은 데이터 유형에 대해 대 / 소문자를 구분하는 (해체) 함수를 정의한 bool :: a -> a -> Bool -> a다음 부울 생성 함수와 함께 인수로 사용하는 것입니다. 예를 들어 myCons z f (MyCons x) = f x ; myCons z f _ = z,을 호출하십시오 myCons False (const True) aMyConsValue. 이것은 거의 당신이 쓴 것입니다. 기능 인수 (들)를 통해 한 단계 더 "간접"/ "추상"을가집니다.
Will Ness

답변:


7

언어 확장 LambdaCase를 사용하여을 (를) 사용할 수 \case MyCons _ -> True; _ -> False있지만 문자를 많이 저장하지는 않습니다.

난 당신이 일련의 기능을 쓸 수있는 생각 constructedWith :: (Generic a) => (b -> a) -> a -> Bool, constructedWith2 :: (Generic a) => (b -> c -> a) -> a -> Bool하지만 몇 시간이 물건을 테스트하지 않고 그것을 구현하는 제네릭과 능력이 충분하지 않다. 나는 이것을 시도하고, 그것을 알아낼 수 있거나 막 다른 곳이면 대답을 편집 할 것입니다.

편집 : 네, 할 수 있습니다! 내 코드에 대한 링크는 다음과 같습니다.

https://repl.it/@lalaithion/ConstructedWith

그러나 모든 일반 코드 배관에 http://hackage.haskell.org/package/generic-deriving-1.13.1/docs/Generics-Deriving-ConNames.html 과 같은 것을 사용하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.