【发布时间】:2015-11-26 05:19:36
【问题描述】:
join 与bind 一起定义,以将组合数据结构展平为单个结构。
从类型系统来看,(+) 7 :: Num a => a -> a 可以被认为是Functor,(+) :: Num a => a -> a -> a 可以被认为是Functor 的Functor,如何获得一些关于它的直觉而不是仅仅依赖类型系统?为什么是join (+) 7 === 14?
虽然可以通过函数绑定过程手动步进得到最终结果,但如果能给出一些直觉就好了。
这是来自NICTA 练习。
-- | Binds a function on the reader ((->) t).
--
-- >>> ((*) =<< (+10)) 7
-- 119
instance Bind ((->) t) where
(=<<) ::
(a -> ((->) t b))
-> ((->) t a)
-> ((->) t b)
(f =<< a) t =
f (a t) t
-- | Flattens a combined structure to a single structure.
--
-- >>> join (+) 7
-- 14
join ::
Bind f =>
f (f a)
-> f a
join f =
id =<< f
*Course.State> :t join (+)
join (+) :: Num a => a -> a
*Course.State> :t join
join :: Bind f => f (f a) -> f a
*Course.State> :t (+)
(+) :: Num a => a -> a -> a
【问题讨论】:
-
“
(+) 7 :: Num a => a -> a可以被认为是Functor...”请不要说这样的话。(7+)不是函子,就像说碳原子是钻石一样。函子是(Int ->),即接受类型并从数字到该类型生成函数的类型构造函数。 -
对于函数,
join f = \a -> f a a。因此join (+) = \a -> a + a. -
@leftaroundabout
(+) 7 :: Num a => a -> a不是Num类别的函子吗? -
@Kamel:
Num作为一个类别?呸,让我们看看。它的对象将是数字类型n, m, ...。态射将是函数n -> m等。因此,(7+)采用数字类型并将其映射到...自身,这很公平。但是它以什么方式映射态射呢?不,恐怕这没有任何意义。 -
@Kamel:嗯,你是对的,从数学上讲,这似乎实际上是一个函子。 (有点退化,注意...)无论如何,它不是 function functor。这不会将类型映射到它们自己。关于“Haskell 中的所有函子将类别映射到自身”——你的意思是,它们是 Hask 上的 endofunctors;但这并不意味着他们将对象/类型映射到自己。事实上这是不可能的,因为函子是类型构造函数,而它们的固定点将是“无限类型”。
标签: haskell functional-programming monads category-theory