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

Car*_*mey 8 haskell types type-constructor

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

Prelude> :m Data.Functor
Prelude Data.Functor> :t flip . (flip (<$>))
flip . (flip (<$>))
:: Functor ((->) b) => (b -> a) -> b -> (a -> c) -> c
Run Code Online (Sandbox Code Playgroud)

Mat*_*ick 9

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

就像函数一样,类型构造函数可以部分应用于Haskell.

您可以检查GHCi中的某种东西:

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

ghci> :k (->) Int
(->) Int :: * -> *
Run Code Online (Sandbox Code Playgroud)

所有价值观都有类型 * ; 类型构造有各种样* -> *,* -> * -> *等等.

  • Pedantry模式:所有值都有*类型*类型`*`. (6认同)

Dan*_*zer 5

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

它可以帮助你认识到,<$>对于((->) a)仅仅是(.)

  • 为了更明确一点,我想补充一点,`( - >)`有种`* - >* - >*`而`( - >)a`有种`* - >*`. (3认同)

Lui*_*las 5

要添加到Matt Fenwick和josefg的更多技术答案,((->) a可以将其视为形成依赖于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 = ...
Run Code Online (Sandbox Code Playgroud)

((->) a)Functor,ApplicativeMonad,这意味着类型类操作可用,并且在使用时它们具有非常有用的解释Historical t.

第一个示例:fmap将函数应用于与时间相关的值.所以,例如,

-- The number of persons in a Team, depending on the Day:
membershipCount :: Team -> Historical Day Int
membershipCount = fmap length . membership
Run Code Online (Sandbox Code Playgroud)

应用<*>操作为您提供同时性:

-- The joint membership of team1 and team2, depending on the Day:
(++) <$> membership team1 <*> membership team2 :: Historical Day [Person]
Run Code Online (Sandbox Code Playgroud)

实际上,既然我们有,instance Monoid [a]并且instance Monoid m => Monoid t -> m,前面的例子可以像这样写:

import Data.Monoid

membership team1 ++ membership team2
Run Code Online (Sandbox Code Playgroud)

Monad为您提供作文:

personToManager :: Person -> Historical Day Manager
personToManager = ...

managerToVP :: Manager -> Historical Day VP
managerToVP = ...

personToVP :: Person -> Historical Day VP
personToVP p = personToManager p >>= managerToVP
Run Code Online (Sandbox Code Playgroud)

另请注意,((->) r这与Reader rmonad 完全相同.如果你理解上面的代码,你几乎可以理解Reader.


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