也许是打字稿中的一种类型

时间:2018-05-28 22:04:46

标签: typescript haskell functional-programming

我想在haksell中的typescript中构造一个Maybe a类型:

data Maybe a = Just a | Nothing

似乎在typescript中执行此操作的方式是:

interface Nothing { tag "Nothing }
type Maybe<T> = T | Nothing

我想做一个功能:

function foo(x : string) : Maybe<T> {
    return Nothing
}

类似于:

foo : String -> Maybe a
foo _ = Nothing

但是这在typescript中不起作用。在打字稿中返回值Nothing的正确方法是什么?如果可能,我想避免使用null

___________________________________________________-

编辑:如果函数foo将返回 Nothing,那将非常很好,因为我想模式匹配值稍后构造函数,即:

case blah blah of 
    | Just x -> x + x
    | Nothing -> "no words"

2 个答案:

答案 0 :(得分:5)

根据具体情况,属性和参数可以是voidundefined?可选修饰符。

它&#39; S:

function foo(x : string) : number | void {
    // returns nothing
}

voidundefined类型兼容,但它们之间存在一些差异。前者更适用于函数返回类型,因为后者需要一个具有return语句的函数:

function foo(x : string) : number | undefined {
    return;
}

Maybe可以使用泛型类型实现。显式Nothing类型可以使用唯一符号实现:

const Nothing = Symbol('nothing');
type Nothing = typeof Nothing;
type Maybe<T> = T | Nothing;

function foo(x : string) : Maybe<number> {
    return Nothing;
}

或类(私有字段可用于防止变形):

abstract class Nothing {
    private tag = 'nothing'
}
type Maybe<T> = T | typeof Nothing;

function foo(x : string) : Maybe<number> {
    return Nothing;
}

请注意,类类型指定类实例类型,并且在引用类时需要使用typeof

或者一个对象(如果可能需要输入鸭子):

const Nothing: { tag: 'Nothing' } = { tag: 'Nothing' };
type Nothing = typeof Nothing;
type Maybe<T> = T | Nothing;

function foo(x : string) : Maybe<number> {
    return Nothing;
}

答案 1 :(得分:1)

以@ estus-flask的答案为基础。让我们从Nothing类型开始。

const nothing = Symbol('Nothing');

type Nothing = typeof nothing;

现在您可以访问类型和值。但是,您不能对价值做很多事情。您甚至无法使用=====进行比较(它将始终返回false),但是有一种解决方法,我们很快就会看到。

另一方面,如果计划使用+包裹的Just运算符,则必须谨慎行事,考虑到+运算符只能根据打字稿编译器与stringnumber类型一起使用。因此,这行不通:

type Maybe<A> = A | Nothing

您可能会想写:

type Maybe<A extends string> = A | Nothing

但是,用两个字符串调用时,+的返回类型始终是string,即使参数是字符串文字类型。因此,上面的代码等于:

type MaybeString = string | Nothing

但是您也可以创建:

type MaybeNumber = number | Nothing

// and

type Maybe<A extends string | number> = A | Nothing

最后,您要实现的功能将是(包括一个助手):

const isNothing = (a: MaybeString): a is Nothing => a.toString() === 'Symbol(Nothing)'; //  this works because string, number and Symbol primitives each have a `toString` method

const foo = (a: MaybeString): MaybeString => {
  if (isNothing(a)) {
    return nothing;
  } else {
    return a + a;
  }
};

作为奖励,这是一个可行的示例maybe-type-with-nothing