gpt4 book ai didi

haskell - 与 Haskell 交互使用串行端口

转载 作者:行者123 更新时间:2023-12-02 20:58:39 25 4
gpt4 key购买 nike

我正在尝试使用 Haskell 的交互模式通过串行端口向 Lego NXT 发送消息,但我不知道如何使用 serialport功能正常。

我有一条消息应该在 NXT 上播放 ByteString 类型的提示音

> let message = pack ([6, 0 ,0, 3, 224, 1, 208, 7]::[Word8])

我可以使用openSerial打开串行端口。

openSerial :: FilePath -> SerialPortSettings -> IO SerialPort
> let mybrick = openSerial "/dev/tty.NXT-DevB" defaultSerialSettings

但后来我陷入困境。我应该如何使用send功能?

send :: SerialPort -> B.ByteString -> IO Int
> send mybrick message

这给了我以下错误消息。

<interactive>:31:6:
Couldn't match expected type `SerialPort'
with actual type `IO SerialPort'
In the first argument of `send', namely `mybrick'
In the expression: send mybrick message
In an equation for `it': it = send mybrick message

最佳答案

您需要对您的 Monad 计算进行排序。我会根据您的情况写得笼统、简单。

<小时/>

你遇到的问题是你有一个函数 f::A -> IO B 和另一个函数 g::B -> IO C 感觉它们应该可以组合,但不完全是——第二个函数需要一个plain B,而不是第一个函数返回的IO B .

这正是 Monad 的力量发挥作用的地方。知道 IO 是一个 monad,我们可以使用像 (>=>)::Monad m => (a -> m b) -> (b -> m c) -> 这样的函数a -> m c 组合这些 Monad 函数。事实上,f >=> g::A -> IO C 已经像我们所要求的那样了。

我们还可以使用 do 表示法,这需要我们“绑定(bind)”f 的返回类型,然后将其应用于 g获取输出。

\a -> do b <- f a
g b

这又给了我们一个A -> IO C类型的函数。事实上,这个do表示法基本上就是(>=>)的定义。

<小时/>

那么这如何适用于您的特定情况呢?嗯,

let mybrick = openSerial "/dev/tty.NXT-DevB" defaultSerialSettings

为您提供一个mybrick::IO SerialPort值。为了使用 send::SerialPort -> ByteString -> IO Int,我们需要从 IO Monad 中“解开”mybrick 。所以我们可以使用 do 表示法

do sp <- mybrick
send sp message

或者,为了让一切变得更简洁,我们可以使用 do 表示法运行整个计算

do mybrick <- openSerial "/dev/tty.NXT-DevB" defaultSerialSettings
send mybrick message

关于haskell - 与 Haskell 交互使用串行端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16246277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com