purescript 中的应用函子和记录

Mik*_*ike 2 haskell purescript

在 Haskell 中,我习惯于做这样的事情。

data Foo = Foo { foo :: String, bar :: String }

mFoo :: (Monad m) => m String -> m String -> m Foo
mFoo foo bar = Foo <$> foo <*> bar
Run Code Online (Sandbox Code Playgroud)

但是,这在 purescript 中不起作用。有没有办法实现相同的结果,即保留记录语法,同时在构建实例时允许通过应用函子部分应用?

谢谢!

pal*_*luh 8

在 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: _ }
Run Code Online (Sandbox Code Playgroud)

和一个单态等价物:

type Foo = { x :: String, y :: String }

mFoo :: forall m. Apply m => m String -> m String -> m Foo
mFoo = Control.Apply.lift2 {x: _, y: _ }
Run Code Online (Sandbox Code Playgroud)

使用精彩的 try.purescript.org + 自定义要点的“现场演示”:

https://try.purescript.org/?gist=a37f5f0c50e0640e34ea5a4788c0c999

当然,使用 a newtypearoundRecord也有实用价值,例如:

newtype Foo' = Foo' { x :: String, y :: String }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我会提出以下建议:

mFoo'' foo bar = map Foo' $ { x: _ , y: _ } <$> foo <*> bar
Run Code Online (Sandbox Code Playgroud)

但我认为这可以用我不知道的更优雅和更短的方式表达:-)

编辑:

这可能是更好的语法,使用ado

mFoo''' foo bar = Foo' <$> ado
  x <- foo
  y <- bar
  in
    { x, y }
Run Code Online (Sandbox Code Playgroud)