Как реализовать конструкцию Haskell * Maybe * в D? - PullRequest
4 голосов
/ 13 декабря 2011

Я хочу реализовать Maybe из Haskell в 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;
}

Haskell Может быть определение:

data  Maybe a = Nothing | Just a

Ответы [ 3 ]

5 голосов
/ 13 декабря 2011

что если бы вы использовали это

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 голосов
/ 14 декабря 2011

Посмотрите на std.typecons.Nullable .Это не совсем то же самое, что Maybe в Haskell, но это тип, который может содержать значение любого типа, для которого он создан.По сути, это похоже на Maybe на Haskell, хотя синтаксически это немного по-другому.Источник здесь , если вы хотите посмотреть на него.

4 голосов
/ 13 декабря 2011

Я не использовал библиотеку 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 может вести себя вполне естественно. Кроме того, я шаблонизировал структуру Maybe, поэтому ее можно использовать с любым типом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...