纯脚本中的应用函子和记录
Applicative functors and records in purescript
在Haskell,我已经习惯了这样的事情。
data Foo = Foo { foo :: String, bar :: String }
mFoo :: (Monad m) => m String -> m String -> m Foo
mFoo foo bar = Foo <$> foo <*> bar
但是,这在纯脚本中不起作用。有没有办法实现相同的结果,即保持记录语法,同时在构建实例时允许通过应用函子进行部分应用?
谢谢!
在 PureScript 中,您不必预先定义此类记录类型。多态版本:
mXY :: forall a b m. Apply m => m a -> m b -> m { x :: a, y :: b }
mXY foo bar = { x: _, y: _ } <$> foo <*> bar
-- | which can be rewritten using lift2:
mXY' = Control.Apply.lift2 { x: _, y: _ }
和一个等价的单态:
type Foo = { x :: String, y :: String }
mFoo :: forall m. Apply m => m String -> m String -> m Foo
mFoo = Control.Apply.lift2 {x: _, y: _ }
使用精彩 try.purescript.org + 自定义要点的“现场演示”:
https://try.purescript.org/?gist=a37f5f0c50e0640e34ea5a4788c0c999
当然,在 Record
左右使用 newtype
也有实用价值:
newtype Foo' = Foo' { x :: String, y :: String }
在这种情况下,我会提出如下建议:
mFoo'' foo bar = map Foo' $ { x: _ , y: _ } <$> foo <*> bar
但我认为这可以用更优雅、更简短的方式表达,我不知道:-)
编辑:
使用 ado
:
可能是更好的语法
mFoo''' foo bar = Foo' <$> ado
x <- foo
y <- bar
in
{ x, y }
在Haskell,我已经习惯了这样的事情。
data Foo = Foo { foo :: String, bar :: String }
mFoo :: (Monad m) => m String -> m String -> m Foo
mFoo foo bar = Foo <$> foo <*> bar
但是,这在纯脚本中不起作用。有没有办法实现相同的结果,即保持记录语法,同时在构建实例时允许通过应用函子进行部分应用?
谢谢!
在 PureScript 中,您不必预先定义此类记录类型。多态版本:
mXY :: forall a b m. Apply m => m a -> m b -> m { x :: a, y :: b }
mXY foo bar = { x: _, y: _ } <$> foo <*> bar
-- | which can be rewritten using lift2:
mXY' = Control.Apply.lift2 { x: _, y: _ }
和一个等价的单态:
type Foo = { x :: String, y :: String }
mFoo :: forall m. Apply m => m String -> m String -> m Foo
mFoo = Control.Apply.lift2 {x: _, y: _ }
使用精彩 try.purescript.org + 自定义要点的“现场演示”:
https://try.purescript.org/?gist=a37f5f0c50e0640e34ea5a4788c0c999
当然,在 Record
左右使用 newtype
也有实用价值:
newtype Foo' = Foo' { x :: String, y :: String }
在这种情况下,我会提出如下建议:
mFoo'' foo bar = map Foo' $ { x: _ , y: _ } <$> foo <*> bar
但我认为这可以用更优雅、更简短的方式表达,我不知道:-)
编辑:
使用 ado
:
mFoo''' foo bar = Foo' <$> ado
x <- foo
y <- bar
in
{ x, y }