我跑了:t fmap (*) (Just 5)
并得到了
fmap (*) (Just 5) :: Num a => Maybe (a -> a)
fmap的类型声明说
fmap :: Functor f => (a -> b) -> f a -> f b
我认为(*)
被视为(a -> (a -> a))
并且对应于fmap类型声明的(a -> b)
部分,我是否正确?如果(a -> a)
部分对应b
,为什么我不能执行以下操作?让b
代表lambda函数吗?
foo :: a -> b
foo x = (\y -> y + 3)
答案 0 :(得分:5)
您的签名中隐含forall
:
foo :: forall a b. a -> b
这意味着您的功能必须适用于 任何 a
和b
。让我们来看看你的功能:
foo x = (\y -> y + 3)
由于x
在=
的右侧没有受到限制,因此它符合要求:它可以是任何类型。但是,您的右侧有以下类型:
ghci> :t (\y -> y + 3)
Num k => k -> k
请记住,您的原始函数表示b
的选择可以是任意的。但是,您的函数正在将返回类型限制为b ~ Num k => k -> k
。你必须使用
foo :: Num b => a -> b -> b
顺便说一句,foo的类型已经表明你不会使用第一个参数,因为没有办法以一般的方式组合不同类型的两个值。实际上,可以证明某些foo
const bar
bar :: Num b => b -> b
为forall a b. a -> b
。
function tytPreGetBool(pre) {
return localStorage.getItem(pre) == 'true' ? true : false;
}
的函数。答案 1 :(得分:1)
在您的初始示例中,由于a
和Num
,5
被限制为(*)
的实例。
:type 5
5 :: Num a => a
:type (*)
(*) :: Num a => a -> a -> a
{J} (a->a)
与[{1}}类型b
统一是正确的。
fmap
因此:
:type (\y -> y + 3)
(\y -> y + 3) :: Num a => a -> a
正如Willem Van Onsem所说,:type foo
foo :: Num a => t -> a -> a
意味着"任何你喜欢的类型",而不是"任何符合我无法提及的无形约束的类型"。