특정 유형 또는 해당 하위 유형을 인수 중 하나로 받아들이는 함수를 작성하려고 시도하고 유형 또는 해당 하위 유형의 값을 리턴합니다.유연한 형식 인수 및 반환 값이있는 함수?
[<AbstractClass>]
type Spreader() =
abstract Fn : unit -> unit
type Fire() =
inherit Spreader()
override self.Fn() =()
type Disease() =
inherit Spreader()
override self.Fn() =()
let spread (spr:#Spreader) : #Spreader =
match spr with
| :? Fire -> Fire()
| :? Disease -> Disease()
| _ -> failwith "I don't get it"
분명히 이것은 작동하지 않지만 내가하려는 일을하게됩니다.
처음에는 Spreader 유형에서 추상 함수를 구현하고 하위 유형에서이를 오버라이드했으나이를 피하기 위해 업 캐스팅이 필요했습니다.
이 것이 가능합니까? 제네릭을 살펴보고 있지만 F # 구현에 대해 아직 이해하지 못했습니다. 나는 차별 노동 조합을 사용하는 제안에 대해서는 편집 2010년 7월 8일 태평양 표준시 17시 30분
, 내가 그 전에 시도 것입니다. 문제는 내가 기본 유형의 멤버로 정의한 모든 함수가 분기를 처리해야한다는 것입니다. 예를 들어 : 아무 의미가없는, 너무,
type strength = float32
type Spreader =
| Fire of strength
| Disease of strength
member self.Spread() =
match self with
| Fire str -> Fire str
| Disease str -> Disease str
member self.Burn() =
match self with
| Fire str -> Fire str
| _ -> failwith "Only fire burns"
확산 기능은 여기에 잘 작동하지만 난 화재 굽기 싶은 경우에, 나는 질병을 제공해야합니다. 예를 들어,
나는 Disease.Burn하려고 같은 불법적 인 일을 할 수있는 사용자가 가능한 시도에 허용 할, 그러나 나는 사방에 옵션 유형의 무리를 반환하고 싶지 않습니다
member self.Burn() =
match self with
| Fire str -> Some(Fire str)
| _ -> None
저는 Burn 기능을 Fire Spreader에만 엄격하게 적용하고 질병 확산기에 대해서는 정의하지 않았습니다.
또한 속성에 대해서도 마찬가지입니다. 불에 질병이 있다는 것을 이해시키지 못하게하고, 그 반대의 경우도 있습니다. 또한 점 표기법을 사용하여 스프레드 어의 강도 값에 액세스 할 수 있기를 바란다. 어쨌든 내가 그런 식으로 액세스하는 다른 멤버를 가지게 될 것이므로, 멤버를 정의해야하는 것은 이상하게 보일 수도있다. 객체에 캡슐화됩니다. (예 : 질병의 str -> ...)
또 다른 옵션은 스프레더 유형에서 스프레드 및 굽기 기능을 간단히 분리하는 것입니다. 그런 다음 (1) 추악한 업 캐스팅이나 제네릭 코드 (2) SpreadFire와 SpreadDisease라는 이름을 지어야했기 때문에 (SpreadFire와 SpreadDisease와 같은) Spread의 경우를 빨아들이는 Fire and Disease를위한 함수를 완전히 분리했다. (함수형이 기묘하게 오버로딩되기 때문에 허용되지 않음).
F #의 멍청한 놈으로, 나는 모든 비판과 제안을 환영한다. :)
편집 2010년 7월 9일 태평양 표준시 08시 45분
존 Harrop에 "왜 당신이 사용하는 보강 및 회원?"
실제 코드의 형식이 수학 집중식이기 때문에 초기화시 특정 값을 사전 계산하고 멤버로 저장합니다.
Jon Harrop : "왜 Speader 유형에만 적용 할 수 있는지 레코딩하고 싶습니까?"스프레더의 구성원으로 기능을 구현하고, 분리하는 사이에, 그러나, 나는이 찢어졌다. 나는 그것이 전적으로 화재에 적용 할. 스프레더에 적용 할 굽기 원하지 내가 쓴 것처럼
, 내가 할 스프레더 유형의 IT (불일치 냄새.)
존 Harrop에가 :. "당신의 FN 구성원의 목적은 무엇인가?"
죄송합니다, 그건 그냥 외부 코드가 무시하시기 바랍니다했다
.Jon Harrop : "왜 인터페이스 대신 추상 클래스를 사용 했습니까?"
대부분 코드 가독성 및 효율성. 그 인터페이스 중 하나를 사용하기 위해 인터페이스에 업 캐스트해야하는 것이 싫다.
Jon Harrop : "왜 강점을 float32의 별칭으로 정의 했습니까?"
코드 가독성.
Jon Harrop : "당신이 해결하려고하는 실제 구체적인 문제는 무엇입니까?!"
가독성을 유지하면서 관련 유형에 대한 코드 공유.
흥미롭게도 당신이 제안한 솔루션은 내가 처음 시도한 솔루션입니다 (저는이 F # 일을 1 주일 정도만 했었습니다).하지만 그 솔루션을 버렸습니다. 타입 정의 밖에서 정의 된 함수를 오버로드 할 수 없기 때문에 DU에 내 기본 유형을 랩핑합니다. 나는 근본적인 유형의 잘못된 발로 빠져 나가는 것에 대해 편집증 적이다. (부분적으로는 VS2010에서 F # 리팩터링이 부족하다는 이유로). 함수 프로그래밍은 지금 당장 나에게 큰 관심사가되는 주제이며, 나는 이해를 위해 낚시를하고있다.
편집 2010년 7월 9일 태평양 표준시 22시 30분
사실, I/정말 http://briancarper.net/blog/315/functional-programming-hurts-me에서 저자 동의 (함수형 프로그래밍을 좋아하지 않는 시작 해요 - 내가 한 번 더 피보나치가 표시되는 경우 또는 F #으로 코딩 예를 팩토리얼 튜토리얼 또는 교과서, 내가 찾은 다음 얼간이를 찌를거야).
Jon이 전시 한 경멸 (아래)에서 내가 여기있는 누군가가 내 최신 응답 (특정 작업을하는 이유 설명)에서 다시 쏠 수 있기를 바랬습니다. 나는 거만한 엘리트들로부터 FP를 배우기를 원합니다. 그들의 코담배들은 그들의 sh * t가 악취가 나지 않는다고 생각합니다.
것은 내가 돈 '브라이언의 존에서 솔루션 및
spread2
달리이 버전은 위의 다음과 같은 일을해야한다는 것을 의미는 인수로 얻는 하나와 같은 하위 유형을 반환 Jon, Brian, Tomas가 이미 가지고있는 것보다 더 말할 것도 없지만, 그 가치는 무엇인가를 위해, 언어를 해킹하고 해킹하여 무언가를 작동 시키면 거의 항상 잘못된 것을하고 있음을 의미합니다. 이 경우 상속은 C#에서 일반적으로 사용되는 관용구가 아니므로 클래스 대신 일치 할 수있는 공용체처럼 관용적 인 무언가를 사용하고 싶을 것입니다.실망하지 마십시오. 거의 모든 사람들이 F # 구문을 사용하여 처음 C#을 작성합니다 (http://stackoverflow.com/questions/1883246/). 숙어를 익히면 언어를 쉽게 사용할 수 있습니다. – Juliet
조언 주셔서 감사합니다, 줄리엣. 나는 당신의 훈계를 염두에 두겠다. 당분간, 나는 Jon의 제안 (아이러니하게도이 프로젝트에서 가장 먼저 수행 한 솔루션 임)을 제시했다. – MiloDC