4

I want to implement Maybe from Haskell in D, just for the hell of it. This is what I've got so far, but it's not that great. Any ideas how to improve it?

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;
}

Haskell Maybe definition:

data  Maybe a = Nothing | Just a
menjaraz
  • 7,551
  • 4
  • 41
  • 81
Arlen
  • 6,641
  • 4
  • 29
  • 61

3 Answers3

5

what if you use this

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;
}

personally I'd use tagged union and structs though (and enforce it's a Just when getting the value)

ratchet freak
  • 47,288
  • 5
  • 68
  • 106
4

I haven't used the Maybe library, but something like this seems to fit the bill:

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);
}

With some creative operator overloading, the Maybe struct could behave quite naturally. Additionally, I've templated the Maybe struct, so it can be used with any type.

Justin W
  • 2,077
  • 12
  • 17
4

Look at std.typecons.Nullable. It's not exactly the same as Maybe in Haskell, but it's a type which optionally holds a value of whatever type it's instantiated with. So, effectively, it's like Haskell's Maybe, though syntactically, it's a bit different. The source is here if you want to look at it.

Jonathan M Davis
  • 37,181
  • 17
  • 72
  • 102
  • I looked at the source code at it looks similar to what Justin has posted. If it's in Phobos, why bother reinventing the wheel? I'll use Nullable, :) – Arlen Dec 13 '11 at 23:55
  • True, not exactly like Haskell `Maybe`, but close enough. – Arlen Dec 13 '11 at 23:55
  • Whether it suits your pruposes depends on what you're trying to do. In general, I'd encourage you to use `Nullable`, because it's in the standard library, but if your main purpose is simply to learn (as your question implies might be the case), then that's different. – Jonathan M Davis Dec 14 '11 at 03:01