2014-11-12 7 views
2

나중에 계산식의 표준 방법 중 하나에서 사용할 수있는 계산식에 메서드 또는 독립 실행 형 함수를 만들 수 있습니까?계산 식의 매개 변수에 액세스 할 수 있습니까?

나는 이런 식으로 뭔가 싶어 :

type FormletBuilder(ctx : HttpContext) = 

    let get_int = 
     match Int32.TryParse (ctx.Request.["foo"]) with 
     | (true, n) -> Some n 
     | _ -> None 

    //similar definitions for get_date, get_non_empty_str, etc... 

    member x.Bind (read : 'a option, f : 'a -> option 'a) = 
     match read with 
     | Some x -> f(x) 
     | None -> None  

    member x.Return (obj) = Some obj 
    member x.Zero() = None 



    let person = formlet ctx { 

     let! id = get_int "id" 
     let! name = get_non_empty_str "fullname" 

     return Person(id, name) 
    } 

을하지만 컴파일러는 get_int가 정의되지 않은 것을 불평.

+0

실제로 여기서 무엇을하려고합니까? 당신이 갖고 싶은 것은 HttpContext가 환경 인 독자 모나드입니다. 이 경우 빌더의 인수가 아니라 계산을 통해 스레드 된 상태의 일부가됩니다. 그런 다음 더 이상 빌더에 묶이지 않고 외부에서 HttpContext를 가져올 수 있으므로 get_int 등을 별도의 모듈에 가질 수 있습니다. – scrwtp

+0

@scrwtp - 오히려 이것이 Maybe 모나드라고 생각했습니다. HttpContext 객체에서 * 및 * 파싱 값을 읽는 중입니다. 그러나 이러한 작업 중 하나 또는 둘 모두가 실패 할 수 있습니다 (예 : "id"라는 값을 읽었지만 int로 파싱되지 않음). 예제 코드는 약간 단순화되었습니다. 'Option' 대신'ReadAttempt' 타입을 사용합니다. <'t> = 성공 't | 실패한 문자열'. –

+0

좋습니다. 나는 내 생각의 일부를 답으로 추가 할 것이다. – scrwtp

답변

2

let bindings in class definitions은 항상 비공개입니다. 대신 member을 정의 할 수 있습니다.

쉬운 솔루션에 대한

, 당신은 할 수 :

let formlet = FormletBuilder(ctx) 
let person = formlet { 
    let! id = formlet.get_int "id" 
    ... 
} 
+0

고맙습니다.하지만 get_int를 멤버로 정의하더라도 계산식 내에서 사용할 수는 없습니다. –

+0

네가 맞아. 내 대답을 업데이트했습니다. – Daniel

1

내가 지금 이해 당신이 실제로 어쩌면 모나드되고 싶어하고, 워크 플로우 인수는 몇 가지 문법 설탕을 사용하도록 그냥 무엇?

  1. 이동 하스켈 거기에 모든 방법을 그것의 아마 독자 부품 모두 유형에 명시되어 있도록하는 MaybeReader 모나드를 구현,
  2. : 그렇다면, 당신이하고 고려할 수있는 몇 가지 다른 일이있다
  3. 설탕을 버리십시오 - 실제로 핵심 빌더 구성원의 컨텍스트가 필요 없다는 것을 알고 있습니까? 그렇다면 어쩌면 빌더에게 논쟁의 여지가 없었을 것입니다. 어쩌면 모나드가 깨끗하고 get_int 등을 적절한 모듈로 옮기고 HttpContext를 명시 적으로 인자로 취하게합니다.
  4. F # 3.0 이상을 사용하는 경우 get_int 등을 워크 플로의 사용자 지정 작업으로 정의 할 수 있으므로 원하는 구문을 효과적으로 제공 할 수 있습니다. Tomas Petricek의 약 good post입니다.
  5. 2. 및 3을 결합하십시오. - 많은 수의 사용자 정의 연산 대신에 HttpContext -> 'a 함수를 취하여 ctx을 적용 할 하나가 - ask입니다. 효과적으로 리더의 진폐 된 버전. 그런 다음 get_int 등을 적절한 모듈로 옮길 수 있습니다.
+0

사려 깊은 대답에 감사드립니다. 네 말이 맞아, 설탕을 주로 먹었어. 내 질문을 게시하기 전에, 나는 사용자 지정 연산자를 보았지만'for..in..do' 구문을 사용해야하기 때문에 적합하지 않은 것으로 보였다. 나는 # 2 베스트를 좋아한다 : 나는 필요한 메소드를 지원하기 위해 단순히 HttpContext를 확장 할 것이다. –

+0

@RodrickChapman : 맞춤 작업에 대해서는 놀랍기 때문에 루프에 묶이지는 않을 것입니다. 결코 그들을 사용하지 마십시오. – scrwtp