'(( - >)a)'是什么意思?

时间:2012-12-17 00:37:25

标签: haskell types type-constructor

我之前看过这种类型而不知道它意味着什么。这是否意味着什么? 和/或它有名字吗?

Prelude> :m Data.Functor
Prelude Data.Functor> :t flip . (flip (<$>))
flip . (flip (<$>))
:: Functor ((->) b) => (b -> a) -> b -> (a -> c) -> c

3 个答案:

答案 0 :(得分:9)

实际上,((->) a)不是类型,而是部分应用的类型构造函数

就像函数一样,类型构造函数可以在Haskell中部分应用。

您可以查看GHCi中种类的内容:

ghci> :k (->)
(->) :: * -> * -> *

ghci> :k (->) Int
(->) Int :: * -> *

所有值都有types of kind *;类型构造函数有* -> ** -> * -> *等类型

答案 1 :(得分:5)

在Haskell中,(->) a来自a -> something。请记住,您可以使用parans将操作符转换为带前缀的函数。即(+) 1 1 == 2。所以在这种情况下,“operator”是类型构造函数->。它是以这种方式使用的,因为仿函数需要一个带有1个变量的类型构造函数,但->有2个。所以我们部分应用它。

可能会让您意识到<$>的{​​{1}}只是((->) a)

答案 2 :(得分:5)

要添加到Matt Fenwick和josefg的更多技术答案,可以将((->) a读作形成依赖于a的值的类型构造函数。一个例子:假设您的团队成员随时间变化。表示这种情况的一种可能方式是:

-- | The type of a's that depend on a point in time, using t as the timeline type.
type Historical t a = t -> a

observe :: Historical t a -> t -> a
observe = ($)

-- | The membership of a team is a list of persons whose composition can change
-- from day to day.
membership :: Team -> Historical Day [Person]
membership = ...

((->) a)FunctorApplicativeMonad,这意味着类型类操作可用,并且与{{1}一起使用时它们具有非常有用的解释}}

第一个例子:Historical t将函数应用于与时间相关的值。例如,

fmap

Applicative -- The number of persons in a Team, depending on the Day: membershipCount :: Team -> Historical Day Int membershipCount = fmap length . membership 操作为您提供 simultaneousity

<*>

实际上,由于我们有-- The joint membership of team1 and team2, depending on the Day: (++) <$> membership team1 <*> membership team2 :: Historical Day [Person] instance Monoid [a],因此前面的示例可以这样写:

instance Monoid m => Monoid t -> m

Monad为您提供作文:

import Data.Monoid

membership team1 ++ membership team2

另请注意,personToManager :: Person -> Historical Day Manager personToManager = ... managerToVP :: Manager -> Historical Day VP managerToVP = ... personToVP :: Person -> Historical Day VP personToVP p = personToManager p >>= managerToVP ((->) r monad完全相同。如果您理解上面的代码,那么您非常了解Reader r


编辑:我应该澄清时间相关的值只是函数/ Reader monad的一次使用。还有其他用途; Reader monad的经典示例用例是通过计算来线程化配置值。正如上面的例子所示,它有更多的用途,而不仅如此。