2011-12-13 1 views
4

하스켈이 D에서 Maybe을 구현하고 싶습니다. 이것은 내가 지금까지 가지고있는 것이지만, 그렇게 좋지는 않다. 어떤 아이디어를 개선하는 방법?하스켈을 구현하는 방법 * 아마 D에서?

class Maybe(a = int){ } //problem 1: works only with ints 

class Just(alias a) : Maybe!(typeof(a)){ } 

class Nothing : Maybe!(){ } 


Maybe!int doSomething(in int k){ 

    if(k < 10) 
    return new Just!3; //problem 2: can't say 'Just!k' 
    else 
    return new Nothing; 
} 

하스켈 어쩌면 정의 : 값을 받고 바로 그 때

data Maybe a = Nothing | Just a 

답변

4

std.typecons.Nullable을 확인하십시오. 하스켈에서는 정확히 Maybe과 같지 않지만 인스턴스화 된 모든 유형의 값을 선택적으로 보유하는 유형입니다. 그래서 효과적으로, Haskell의 Maybe과 같지만 구문 적으로는 조금 다릅니다. 당신이 그것을보고 싶다면 출처는 here입니다.

+0

저스틴이 게시 한 것과 비슷한 소스 코드를 보았습니다. Phobos에있는 경우 왜 바퀴를 다시 만들어야합니까? Nullable을 사용할 것입니다. :) – Arlen

+0

하스켈과 다를 바는 아니지만 충분히 가깝습니다. – Arlen

+0

그것이 당신의 목적에 적합한지는 당신이하려는 일에 달려 있습니다. 일반적으로 표준 라이브러리에 있기 때문에'Nullable '을 사용하는 것이 좋습니다. 그러나 주 목적이 단순히 (귀하의 질문이 암시하는 것처럼) 배우는 것이면 다른 것입니다. –

5

class Maybe(T){ } 

class Just(T) : Maybe!(T){ 
T t; 
this(T t){ 
this.t = t; 
} 
} 
class Nothing : Maybe!(){ } 


Maybe!int doSomething(in int k){ 

    if(k < 10) 
    return new Just!int(3); 
    else 
    return new Nothing; 
} 

를 사용하는 경우 개인적으로 내가 비록 노동 조합 및 구조체 태그 사용하십시오 어떤

(그리고 enforce 그것은이다)

4

나는 Maybe 라이브러리를 사용하지 않았지만, 이와 비슷한 것은 적합하다고 보입니다. 청구서 :

import std.stdio; 

struct Maybe(T) 
{ 
    private { 
     bool isNothing = true; 
     T value; 
    } 

    void opAssign(T val) 
    { 
     isNothing = false; 
     value = val; 
    } 

    void opAssign(Maybe!T val) 
    { 
     isNothing = val.isNothing; 
     value = val.value; 
    } 

    T get() @property 
    { 
     if (!isNothing) 
      return value; 
     else 
      throw new Exception("This is nothing!"); 
    } 

    bool hasValue() @property 
    { 
     return !isNothing; 
    } 
} 

Maybe!int doSomething(in int k) 
{ 
    Maybe!int ret; 

    if (k < 10) 
     ret = 3; 
    return ret;  
} 

void main() 
{ 
    auto retVal = doSomething(5); 
    assert(retVal.hasValue); 
    writeln(retVal.get); 

    retVal = doSomething(15); 
    assert(!retVal.hasValue); 
    writeln(retVal.hasValue); 
} 

일부 창조적 연산자가 오버로드되면 구조체가 자연스럽게 작동 할 수 있습니다. 또한 Maybe 구조체를 템플릿으로 만들었으므로 모든 유형과 함께 사용할 수 있습니다.