显式类型传递是否不等同于类型推断(就表达能力而言)?
Is explicit type passing not equivalent to type inference (in terms of expressiveness)?
我尝试将 traverse
/sequenceA
翻译成 Javascript。现在 Haskell 实现的以下行为给我带来了麻烦:
traverse (\x -> x) Nothing -- yields Nothing
sequenceA Nothing -- yields Nothing
traverse (\x -> x) (Just [7]) -- yields [Just 7]
sequenceA (Just [7]) -- yields [Just 7]
作为一个 Haskell 新手,我想知道为什么第一个表达式完全有效:
instance Traversable Maybe where
traverse _ Nothing = pure Nothing
traverse f (Just x) = Just <$> f x
pure Nothing
在这种情况下不应该工作,因为没有可以放入值的最小应用上下文。似乎编译器懒惰地检查这个表达式的类型并且因为映射Nothing
上的 id 函数是一个 noop,它只是 "overlooks" 类型错误,可以这么说。
这是我的 Javascript 翻译:
(请注意,由于 Javascirpt 的原型系统对于几个类型 类 是不够的,而且无论如何也没有严格的类型检查,我使用 Church 编码并将类型约束显式传递给函数。)
// minimal type system realized with `Symbol`s
const $tag = Symbol.for("ftor/tag");
const $Option = Symbol.for("ftor/Option");
const Option = {};
// value constructors (Church encoded)
const Some = x => {
const Some = r => {
const Some = f => f(x);
return Some[$tag] = "Some", Some[$Option] = true, Some;
};
return Some[$tag] = "Some", Some[$Option] = true, Some;
};
const None = r => {
const None = f => r;
return None[$tag] = "None", None[$Option] = true, None;
};
None[$tag] = "None";
None[$Option] = true;
// Traversable
// of/map are explicit arguments of traverse to imitate type inference
// tx[$Option] is just duck typing to enforce the Option type
// of == pure in Javascript
Option.traverse = (of, map) => ft => tx =>
tx[$Option] && tx(of(None)) (x => map(Some) (ft(x)));
// (partial) Array instance of Applicative
const map = f => xs => xs.map(f);
const of = x => [x];
// helpers
const I = x => x;
// applying
Option.traverse(of, map) (I) (None) // ~ [None]
Option.traverse(of, map) (I) (Some([7])) // ~ [Some(7)]
显然,这个翻译偏离了 Haskell 的实现,因为我得到了一个 [None]
而我应该得到一个 None
。老实说,这种行为完全符合我的直觉,但我猜直觉对函数式编程没有多大帮助。现在我的问题是
- 我只是犯了一个新手错误吗?
- 或者显式类型传递不等同于类型推断(在表达能力方面)?
GHCi 不会忽略任何类型错误。它默认将不受约束的 Applicative
设置为 IO
,但您只会在 GHCi 提示符(而不是 .hs
源文件)中获得此行为。您可以查看
> :t pure Nothing
pure Nothing :: Applicative f => f (Maybe b)
但还有
> pure Nothing
Nothing
您的 javascript 实现没问题;您为数组传入了一个 Applicative
实例并得到了预期的结果。
我尝试将 traverse
/sequenceA
翻译成 Javascript。现在 Haskell 实现的以下行为给我带来了麻烦:
traverse (\x -> x) Nothing -- yields Nothing
sequenceA Nothing -- yields Nothing
traverse (\x -> x) (Just [7]) -- yields [Just 7]
sequenceA (Just [7]) -- yields [Just 7]
作为一个 Haskell 新手,我想知道为什么第一个表达式完全有效:
instance Traversable Maybe where
traverse _ Nothing = pure Nothing
traverse f (Just x) = Just <$> f x
pure Nothing
在这种情况下不应该工作,因为没有可以放入值的最小应用上下文。似乎编译器懒惰地检查这个表达式的类型并且因为映射Nothing
上的 id 函数是一个 noop,它只是 "overlooks" 类型错误,可以这么说。
这是我的 Javascript 翻译:
(请注意,由于 Javascirpt 的原型系统对于几个类型 类 是不够的,而且无论如何也没有严格的类型检查,我使用 Church 编码并将类型约束显式传递给函数。)
// minimal type system realized with `Symbol`s
const $tag = Symbol.for("ftor/tag");
const $Option = Symbol.for("ftor/Option");
const Option = {};
// value constructors (Church encoded)
const Some = x => {
const Some = r => {
const Some = f => f(x);
return Some[$tag] = "Some", Some[$Option] = true, Some;
};
return Some[$tag] = "Some", Some[$Option] = true, Some;
};
const None = r => {
const None = f => r;
return None[$tag] = "None", None[$Option] = true, None;
};
None[$tag] = "None";
None[$Option] = true;
// Traversable
// of/map are explicit arguments of traverse to imitate type inference
// tx[$Option] is just duck typing to enforce the Option type
// of == pure in Javascript
Option.traverse = (of, map) => ft => tx =>
tx[$Option] && tx(of(None)) (x => map(Some) (ft(x)));
// (partial) Array instance of Applicative
const map = f => xs => xs.map(f);
const of = x => [x];
// helpers
const I = x => x;
// applying
Option.traverse(of, map) (I) (None) // ~ [None]
Option.traverse(of, map) (I) (Some([7])) // ~ [Some(7)]
显然,这个翻译偏离了 Haskell 的实现,因为我得到了一个 [None]
而我应该得到一个 None
。老实说,这种行为完全符合我的直觉,但我猜直觉对函数式编程没有多大帮助。现在我的问题是
- 我只是犯了一个新手错误吗?
- 或者显式类型传递不等同于类型推断(在表达能力方面)?
GHCi 不会忽略任何类型错误。它默认将不受约束的 Applicative
设置为 IO
,但您只会在 GHCi 提示符(而不是 .hs
源文件)中获得此行为。您可以查看
> :t pure Nothing
pure Nothing :: Applicative f => f (Maybe b)
但还有
> pure Nothing
Nothing
您的 javascript 实现没问题;您为数组传入了一个 Applicative
实例并得到了预期的结果。