gpt4 book ai didi

haskell - 重构 where 子句

转载 作者:行者123 更新时间:2023-12-02 20:53:05 29 4
gpt4 key购买 nike

我正在学习 Haskell,所以这可能是一些非常微不足道的事情,但我希望得到一些关于如何重写它以及它如何工作的指示。

我有以下工作代码(使用的包: HTFParsecFlow ):

{-# OPTIONS_GHC -F -pgmF htfpp #-}
{-# LANGUAGE FlexibleContexts #-}

module Main where

import Test.Framework -- assertEqual, assertBool, htfMain, htf_thisModulesTests
import Text.ParserCombinators.Parsec (eof, spaces, parse)
import Flow ((|>))
import Data.Either (isLeft)

whiteSpaces = spaces

test_parse_whitespace = do
mapM_ positive [
"", " ", "\t", "\n", "\r\n", " \r\n ",
" \t \r\n \t \n \r \t "
]
mapM_ negative ["x", " x", "x ", " x ", "\t_\t"]
where
parser = whiteSpaces >> eof
parseIt = parse parser ""
positive str = assertEqual (parseIt str) (Right ())
negative str = assertBool (parseIt str |> isLeft)

main :: IO ()
main = htfMain htf_thisModulesTests

我正在添加一个新的测试,它的 where 部分几乎相同,所以我尝试像这样重构它:

pos_neg_case parser = do
return [positive, negative]
where
fullParser = parser >> eof
parseIt = parse fullParser ""
positive str = assertEqual (parseIt str) (Right ())
negative str = assertBool (parseIt str |> isLeft)

test_parse_whitespace' = do
mapM_ positive [
"", " ", "\t", "\n", "\r\n", " \r\n ",
" \t \r\n \t \n \r \t "
]
mapM_ negative ["x", " x", "x ", " x ", "\t_\t"]
where
[positive, negative] = pos_neg_case whiteSpaces

这不起作用(即使我按照编译器的建议打开 lang. 功能)。

Couldn't match expected type ‘[Char] -> m b0’
with actual type ‘[String -> IO ()]’
Relevant bindings include
test_parse_whitespace' :: m () (bound at test/Spec.hs:21:1)
In the first argument of ‘mapM_’, namely ‘positive’
In a stmt of a 'do' block:
mapM_ positive ["", " ", "\t", "\n", ....]

Couldn't match expected type ‘[Char] -> m b1’
with actual type ‘[String -> IO ()]’
Relevant bindings include
test_parse_whitespace' :: m () (bound at test/Spec.hs:21:1)
In the first argument of ‘mapM_’, namely ‘negative’
In a stmt of a 'do' block:
mapM_ negative ["x", " x", "x ", " x ", ....]

最佳答案

正如您所注意到的,问题在于您添加到的return:

pos_neg_case parser = do
return [positive, negative]
where -- etc.

mapM_的类型是:

GHCi> :t mapM_
mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()

正数负数是已经具有要传递给mapM的适当类型的函数,因此如果您想要pos_neg_case 要将它们作为列表返回,您只需将它们包装在列表中即可。 return 不是关键字;它只是一个将值注入(inject)到单子(monad)上下文中的函数。如果您不需要进行任何此类注入(inject),则不需要return

PS:引用你的答案:

But I had to guess the Parser type, hole was giving me very complex thingy Text.Parsec.Prim.ParsecT s () Data.Functor.Identity.Identity a -> [s -> IO ()].

这是一个非常常见的模式的示例。 ParsecT 是一个具有相当多类型变量的类型构造函数,而 Parser 是其中一些变量的一组通用选择的类型同义词,它允许更整洁的类型签名其中没有明确提及它们。如果您在 documentation 中查找它(索引在这种情况下很有帮助)或者在 GHCi 中使用 :info,你会发现 Parser 只是意味着...

type Parser = Parsec String ()

...和秒差距,依次是...

type Parsec s u = ParsecT s u Identity

...这样扩展Parser同义词就可以得到ParsecT String () Identity,这就是 GHC 在引入类型漏洞时告诉您的。

关于haskell - 重构 where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40450864/

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