Haskell addToLeftPlayerPos的正确实现是什么

Haskell addToLeftPlayerPos的正确实现是什么,haskell,monads,frp,reader,writer,Haskell,Monads,Frp,Reader,Writer,我试图继续函数式反应式编程,但我被第4.2节中的第二个示例卡住了 我得到了reader transformer启动并运行的第一个示例: module Main where import FRP.BearRiver import Control.Monad.Trans.MSF.Reader type Game = Ball type Ball = Int type GameEnv = ReaderT GameSettings data GameSettings = Game

我试图继续函数式反应式编程,但我被第4.2节中的第二个示例卡住了

我得到了reader transformer启动并运行的第一个示例:

module Main where

import FRP.BearRiver    
import Control.Monad.Trans.MSF.Reader

type Game = Ball
type Ball = Int

type GameEnv = ReaderT GameSettings

data GameSettings
    = GameSettings
      { leftPlayerPos  :: Int
      , rightPlayerPos :: Int
      }

ballToRight :: Monad m => MSF (GameEnv m) () Ball
ballToRight =
    count >>> arrM addToLeftPlayerPos
    where
      addToLeftPlayerPos =
          (\n -> (n +) <$> asks leftPlayerPos)

hitRight :: Monad m => MSF (GameEnv m) Ball Bool
hitRight = arrM (\i -> (i >=) <$> asks rightPlayerPos)
一些措辞 当您有一个转换器堆栈时,您必须“提升”您的操作以运行内部monad函数。例如:

type MyMonad a = Transformer1 (Transformer2 IO) a
这里的堆栈是IO的Transformer2的Transformer1。“外部”单子是Transformer1,它将Transformer2与IO的最内部(或底部)单子封装在一起。在您的例子中,堆栈实际上是某个未知monad
m
的读卡器的编写器,一切正常

现在,如果我们想从函数
g::MyMonad
中运行
f::Transformer2 IO a
,我们必须
lift f
。类似地,如果我们有
getLine::IO String
并且希望从
g::Transformer1(transformer2io)a
中运行该字符串,那么我们可以
lift(lift getLine)

举起 如果导入
Control.Monad.Trans.Class
,则可以提升ReaderT操作。例如,
lift(asks…
而不仅仅是
asks…

这确实很有帮助。您评论的错误可能是由于在
checkHitR
中使用了
asks

还有一个类型错误 进行起吊后,我们发现错误:

frosch.hs:23:5: error:
    • Couldn't match type ‘()’ with ‘Int’
      Expected type: MSF (GameEnv m) () Ball
        Actual type: MSF
                       (WriterT [[Char]] (ReaderT GameSettings m)) () ()
这是因为您的
checkHitR
没有返回值
rp
(我认为应该返回)。解决该问题将为我们提供以下最终代码:

module Main where

import FRP.BearRiver
import Control.Monad.Trans.Class
import Control.Monad
import Control.Monad.Trans.MSF.Reader
import Control.Monad.Trans.MSF.Writer

type Game = Ball
type Ball = Int

type GameEnv m =
    WriterT [String] (ReaderT GameSettings m)

data GameSettings
    = GameSettings
      { leftPlayerPos  :: Int
      , rightPlayerPos :: Int
      }

ballToRight :: Monad m => MSF (GameEnv m) () Ball
ballToRight =
    count >>> arrM addLeftPlayerPos >>> arrM checkHitR
    where
      addLeftPlayerPos =
          (\n -> (n +) <$> lift (asks leftPlayerPos))
      checkHitR n = do
          rp <- lift (asks rightPlayerPos)
          when (rp > n) $ tell ["Ball is at " ++ (show n)]
          pure rp
modulemain其中
比尔河进口玻璃钢
导入控制.Monad.Trans.Class
进口管制
导入控制.Monad.Trans.MSF.Reader
导入控制.Monad.Trans.MSF.Writer
类型游戏=球
类型Ball=Int
GameEnv m型=
WriterT[String](ReaderT游戏设置m)
数据游戏设置
=游戏设置
{leftPlayerPos::Int
,rightPlayerPos::Int
}
ballToRight::Monad m=>MSF(GameEnv m)()Ball
棒球=
计数>>>arrM addLeftPlayerPos>>>arrM校验器
哪里
addLeftPlayerPos=
(\n->(n+)抬起(询问左玩家))
checkhitrn=do
rp n)$tell[“球在”++(显示n)]
纯rp

您能提供您尝试的实现和错误吗?当然,我的实现只是我添加到帖子中的错误消息where子句中的一个。此外,我将相关部分添加到了中。您是否尝试
提升(询问leftPlayerPos)
?我还没有测试过,但这是在变压器下面使用monad的正常方式。当然,但这没有多大帮助:
•无法将类型“ReaderT GameSettings m2”与
“WriterT[String](ReaderT GameSettings m)
匹配。。。也就是说:
预期类型:MSF(GameEnv m)()Ball
而不是
实际类型:MSF(ReaderT GameSettings m2)(
frosch.hs:23:5: error:
    • Couldn't match type ‘()’ with ‘Int’
      Expected type: MSF (GameEnv m) () Ball
        Actual type: MSF
                       (WriterT [[Char]] (ReaderT GameSettings m)) () ()
module Main where

import FRP.BearRiver
import Control.Monad.Trans.Class
import Control.Monad
import Control.Monad.Trans.MSF.Reader
import Control.Monad.Trans.MSF.Writer

type Game = Ball
type Ball = Int

type GameEnv m =
    WriterT [String] (ReaderT GameSettings m)

data GameSettings
    = GameSettings
      { leftPlayerPos  :: Int
      , rightPlayerPos :: Int
      }

ballToRight :: Monad m => MSF (GameEnv m) () Ball
ballToRight =
    count >>> arrM addLeftPlayerPos >>> arrM checkHitR
    where
      addLeftPlayerPos =
          (\n -> (n +) <$> lift (asks leftPlayerPos))
      checkHitR n = do
          rp <- lift (asks rightPlayerPos)
          when (rp > n) $ tell ["Ball is at " ++ (show n)]
          pure rp