gpt4 book ai didi

haskell - Linter 说多余的 lambda,但是当按照建议替换时它会给出不同的错误

转载 作者:行者123 更新时间:2023-12-02 15:31:45 27 4
gpt4 key购买 nike

我正在阅读 Real World Haskell - Chapter 10 .

所有函数都有共同的类型 L.ByteString -> Maybe (a, L.ByteString)然后我查看了 StateT 定义,它是 s -> m (a, s) 如果写成 StateT L.ByteString Maybe a,它与上面完全匹配。所以我决定用 monad 转换器重写第一个例子。希望

parseP5 :: StateT L.ByteString Maybe Greymap
parseP5 = do
matchHeader (L8.pack "P5")
skipSpace
width <- getNat
skipSpace
height <- getNat
skipSpace
maxGrey <- getNat
skipSpace
_ <- getBytes 1
bitmap <- getBytes (width*height)
return (Greymap width height maxGrey bitmap)

就可以了。

例如matchHeader函数会变成

matchHeader :: L.ByteString -> StateT L.ByteString Maybe ()
matchHeader prefix = \str ->
if prefix `L8.isPrefixOf` str
then Just ((), str)
else Nothing

但是 linter 说它有多余的 lambda。但是我不知道没有 lambda 怎么写。你能帮我解决这个问题吗?

更新:

当它被替换时:

matchHeader prefix str=
if prefix `L8.isPrefixOf` str
then Just ((), str)
else Nothing

它给出了另一个错误

Couldn't match expected type L8.ByteString -> Maybe ((), L8.ByteString)with actual type StateT L8.ByteString Maybe ()The equation(s) for matchHeader' have two arguments, but its typeL8.ByteString -> StateT L8.ByteString Maybe () has only one

L8.ByteString -> Maybe((), L8.ByteString)StateT L8.ByteString Maybe () 不是一回事吗?

最佳答案

StateT s m a 不是 s -> m (a, s) 的类型别名,而是一个 newtype 包装器,它被算作一个通过类型检查器分离类型,因此您必须使用 StateT 构造函数包装您的 lambda。

import Control.Monad.State
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as L8

matchHeader :: L.ByteString -> StateT L.ByteString Maybe ()
matchHeader prefix = StateT $ \str ->
if prefix `L8.isPrefixOf` str
then Just ((), str)
else Nothing

您也可以使用 StateTMonad 实例编写没有 lambda 的匹配器

matchHeader prefix = do
str <- get
if prefix `L8.isPrefixOf` str
then return ()
else lift Nothing

这使用 get 获取当前状态,然后返回 () 或通过 StateT 转换器“提升”到内部 也许 monad.

上述示例使用与原始代码相同的逻辑,但您可能还想从状态中删除前缀。您还可以使用 MonadPlus 中的 guard 作为 Ørjan 演示来缩短 if 子句。

matchHeader :: L.ByteString -> StateT L.ByteString Maybe ()
matchHeader prefix = do
str <- get
guard (prefix `L8.isPrefixOf` str)
put $ L8.drop (L8.length prefix) str

关于haskell - Linter 说多余的 lambda,但是当按照建议替换时它会给出不同的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25237048/

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