2014-10-20 3 views
6

귀납적 인 정의가 있고 그것을 Haskell에서 데이터 타입으로 정의하고자한다고 가정 해보십시오. 그러나 귀하의 귀납적 정의는 생성 규칙에 '전제 (premisses)'가 특정 구조를 가져야하는 양식의 (많은 귀납적 정의만큼) 것입니다. 예를 들어, 우리는 다음과 같은 정의가 있다고 가정제약 데이터 타입

  • x 경우는 심지어 정수, 다음 T x이 무기이다,
  • xS x이 무기 후, 홀수 인 경우. 지금 T 5S 4를 생성 할 수 있습니다 나는 하스켈의 데이터 유형 (단일로)이 정의하려면

, 내가 분명히

data Weapon = T Int | S Int 

처럼 작성할,이를 위해 작동하지 않습니다 예. 생성자 인수에 제한을 전달하는 자연스러운 방법이 있습니까? 그렇다면 올바른 정의를 내릴 수있는 위의 코드와 비슷한 것을 작성할 수 있습니까? YourModule을 가져올 때 만에, 사용자가 명시 적으로 TS을 만들 수 없습니다 이제

module YourModule (Weapon, smartConstruct) where 

data Weapon = T Int | S Int 

smartConstruct :: Int -> Weapon 
smartConstruct x 
    | even x  = T x 
    | otherwise = S x 

:

+2

대부분 스마트 생성자.'T'와'S'를 직접 사용하여 금지하고 전달 된 숫자를 검증하는'newT'와'newS' 함수를 만듭니다. –

답변

9

당신의 최선의 샷은 사용자 정의 생성자를 명시 적으로 TS를 내보내지만, 허용하지 않는 것입니다 귀하의 smartConstruct 기능.

10

이것은 Haskelly 비트가 아니지만 예를 들어 더 숙성적입니다. Agda : 귀하의 표현의 해석을 변경하여 건설에 의해 강제되도록하십시오.

이 경우 n :: Int 일 경우 even (2 * n)odd (2 * n + 1)입니다. Int이 너무 큰 경우를 핸드웨이에서 제거하면 IntInt 사이에 bijection이 있다고 말할 수 있습니다. 홀수 인 IntInt 사이에 또 ​​하나가 있습니다. 그래서를 사용

,이 표현 선택할 수 있습니다

data Weapon = T Int | S Int 

을하고 값 T n 실제로 T (2 * n)을 나타내고 값 S nS (2 * n + 1)을 대표하도록 해석을 변경합니다. 따라서 어떤 n :: Int을 선택 하든지 T n은 "T -of-2 * n"값으로 간주되므로 유효합니다.

+0

니스. 이런 종류의 트릭에 대한 더 많은 예제를 어디에서 찾을 수 있는지 알고 있습니까? – danidiaz

+2

그리고'Integer'로 핸드 웨이브를 제거 할 수 있습니다. – dfeuer

+2

@danidiaz : Agda 표준 라이브러리에이 패턴의 몇 가지 예가 있습니다. http://agda.github.io/agda-stdlib/html/Data.Integer.html#915 – Cactus

5

당신이 Nats를 사용하기를 원한다면, 상당히 진보 된 타입의 마법을 사용해도 괜찮습니다. GHC.TypeLits을 사용할 수 있습니다.

{-# LANGUAGE DataKinds, GADTs, TypeOperators, KindSignatures #-} 

import GHC.TypeLits 

data Weapon (n :: Nat) where 
    Banana  :: n ~ (2 * m) => Weapon n 
    PointyStick :: n ~ (2 * m + 1) => Weapon n 

banana :: Weapon 2 
banana = Banana 

pointyStick :: Weapon 3 
pointyStick = PointyStick 

잘못된 (홀수/짝수) 숫자로 컴파일되지 않도록 노력하십시오.

편집 : 더 많은 실용적인 방법이 있습니다.

+0

이것은 요청에 이중 일종의 것 같습니다. 흥미 롭 군. – dfeuer

+0

몬티 파이썬 참고 자료에 감사드립니다. – dfeuer

+0

왜 듀얼이라고 생각합니까? 런 타임에 이런 무기를 만드는 데는 어느 정도 시간이 걸릴 필요가 있지만 어렵지 않습니다. 그것은 심지어 바나나와 이상한 뾰족한 막대기 만 만들어 지도록 보장합니다. – ibotty