我想在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"
答案 0 :(得分:5)
根据具体情况,属性和参数可以是void
,undefined
或?
可选修饰符。
它&#39; S:
function foo(x : string) : number | void {
// returns nothing
}
void
和undefined
类型兼容,但它们之间存在一些差异。前者更适用于函数返回类型,因为后者需要一个具有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
运算符,则必须谨慎行事,考虑到+
运算符只能根据打字稿编译器与string
或number
类型一起使用。因此,这行不通:
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