标签: io-monad

如何在带有符号的列表上使用映射 - 即避免使用类型"[IO()]"键入`IO()'?

所以这个问题更多地是关于Monads(尤其是Fay),但是我的例子使用了IO monad.

我有一个函数,其中输入是一个字符串列表,我想逐个打印每个字符串.所以这是我的想法:

funct :: [String] -> ?
funct strs = do
    map putStrLn strs
Run Code Online (Sandbox Code Playgroud)

但是不起作用,因为它返回一个类型[IO()].所以我的问题是,我将如何映射列表,并将其视为我在逐行执行函数,以典型的符号,迭代风格(如下所示)?

funct :: [String] -> IO ()
funct strs = do
    putStrLn (strs !! 0)
    putStrLn (strs !! 1)
    ...
Run Code Online (Sandbox Code Playgroud)

monads haskell io-monad

5
推荐指数
2
解决办法
1015
查看次数

如何映射和连接 FilePaths?

我仍在研究 Haskell,尤其是 IO monad。

我有一个目录路径列表,例如,

["/some/path", "/another/path", "/yet/another/path", "/still/more"]

并且我想将此列表映射到每个路径的完全限定内容列表中(没有...),如下所示:

["/some/path/file.1", "/some/path/somedir", "/some/path/file.2", "/another/path/file.a", "/another/path/a/directory", "/another/path/file.b", "/still/more/file.alpha", ...]

我想我可以用某种双映射来做到这一点,就像这样:

pathItems <- mapM (\pd -> MapM (\contents -> (pd </>) contents) (getDirectoryContents pd) pathDirs

但这不起作用。我得到的错误是这样的:

程序.hs:27:56:
    无法将类型“[]”与“IO”匹配
    预期类型:IO 字符
      实际类型:文件路径
    在表达式中: (pd </>) 内容
    在‘mapM’的第一个参数中,即
      `(\ 内容 -> (pd ) 内容)'

程序.hs:27:84:
    无法匹配预期类型“[FilePath]”
                实际类型为“IO [FilePath]”
    在'mapM'的第二个参数中,即
      `(getDirectoryContents pathDir)'
    在表达式中:
      地图M
        (\ 内容 -> (pd </>) 内容)
        (getDirectoryContents pd)

monads haskell io-monad

5
推荐指数
1
解决办法
630
查看次数

从文件系统动态生成Tasty`TestTree`

我已经使用该Parsec库编写了一个文件解析器.我想使用Tasty测试框架编写一个高级单元测试,以确保解析器正确解析某些给定的文件.

我在以下目录结构中有三个格式良好的文件:

path/to/files -+
               |-> fileA
               |-> fileB
               |-> fileC
Run Code Online (Sandbox Code Playgroud)

我想要:

  1. 获取所有文件 path/to/files
  2. 阅读每个文件的内容
  3. testCase为每个文件创建一个文件,以确保成功解析文件的内容
  4. 这是动态完成的,这样我以后可以添加更多文件,永远不会更改代码

我设法构建了以下内容:

{-# LANGUAGE BangPatterns, FlexibleContexts #-}

module Test.MyParser
  ( testSuite
  ) where

import Control.Arrow              ((&&&))
import Data.Map                   (Map,fromList,toList)
import System.Directory
import System.IO.Unsafe           (unsafePerformIO) -- This is used for a hack
import Test.Tasty                 (TestTree,testGroup,withResource)
import Test.Tasty.HUnit
import Text.Parsec

-- | Determine if an Either is a Right or Left value
--   Useful for determining if a parse attempt was successful …
Run Code Online (Sandbox Code Playgroud)

haskell unit-testing dynamically-generated hunit io-monad

5
推荐指数
1
解决办法
241
查看次数

如何在Haskell中构造一个no-op IO()表达式?

这是我正在编写的特定于域的文件IO函数的摘录:

let
    cp :: FilePath -> IO ()
    cp "." = putStr "" -- OUCH!
    cp ".." = putStr "" -- CRIKEY!
    cp fname = custom logic here...
in mapM_ cp filepaths
Run Code Online (Sandbox Code Playgroud)

我理解mapM_让我们放弃/忽略所有IO ()结果,所以我想要一个更清洁的替代品putStr ""---即.Haskell的"规范"方式来编写"一个不做任何事情的类型正确的无操作IO(或monad)表达式".

从我的新手阅读中我undefined想到了,虽然这个编译并没有引起任何问题,但它会产生一个不需要的stdout打印main.hs: Prelude.undefined(我在这里stack runghc main.hs用作唯一的编码环境---它就足够了,上面的代码将以递归的方式循环通过目录树:这将是(重新)了解更好,或更确切地说"正确"方式的好时机.

monads haskell io-monad

5
推荐指数
1
解决办法
575
查看次数

模拟 BlazeClientBuilder[IO] 以返回模拟客户端[IO]

我正在使用该BlazeClientBuilder[IO].resource方法来获取Client[IO]. 现在,我想模拟客户端进行单元测试,但不知道该怎么做。有没有一个好的方法来嘲笑这个,我会怎么做?

class ExternalCall(val resource: Resource[IO, Client[IO]], externalServiceUrl: Uri) {
def retrieveData: IO[Either[Throwable, String]] = {
for {
  req <- IO(Request[IO](Method.GET, uri = externalServiceUrl))
  response <- resource.use(client => {
    client.fetch[String](req)(httpResponse => {
      if (!httpResponse.status.isSuccess)
        throw new Exception(httpResponse.status.reason)
      else
        httpResponse.as[String]
    })
  })
} yield Right(response)
}
}
Run Code Online (Sandbox Code Playgroud)

来电代码

new ExternalCall(BlazeClientBuilder[IO](global).resource).retrieveData
Run Code Online (Sandbox Code Playgroud)

scala mockito io-monad scala-cats

5
推荐指数
1
解决办法
1723
查看次数

Haskell Monads 和 liftIO 我不明白

您好社区,感谢您的宝贵时间。

\n

我有一个错误,我不确定错误是什么,但我认为问题是:\n没有从ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO)到 的IO 转换器Web.Scotty.Internal.Types.ScottyT

\n

但我想知道为什么编译器与ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO). 这就是为什么我只使用 String 并删除了所有出现的{-# LANGUAGE OverloadedStrings #-}但仍然收到错误。另一方面,这应该是IO [String],不是吗?\n正如你所提到的,我真的不知道是什么ext-1.2.4.1:Data.Text.Internal.Lazy.Text IO)

\n

在另一个地方,我已经liftIO成功使用了一个a -> IO String函数。我想我也以同样的方式使用它们。

\n

我想我慢慢地感觉到了 monad 是什么,但不太确定。我真的不知道为什么我必须使用一个lift函数。

\n

错误信息:

\n
    \xe2\x80\xa2 No instance for (MonadIO\n                         (Web.Scotty.Internal.Types.ScottyT\n                            text-1.2.4.1:Data.Text.Internal.Lazy.Text IO))\n        arising from a use of \xe2\x80\x98liftIO\xe2\x80\x99\n    \xe2\x80\xa2 In a stmt of a \'do\' block:\n        paths <- liftIO $ getAllFilePaths2 path\n      In the expression:\n        do …
Run Code Online (Sandbox Code Playgroud)

monads haskell lifting io-monad scotty

5
推荐指数
1
解决办法
470
查看次数

如何在 IO 异常处理程序中保留 monad 堆栈的状态?

考虑以下程序。

import Control.Monad.State
import Control.Monad.Catch

ex1 :: StateT Int IO ()
ex1 = do
    modify (+10)
    liftIO . ioError $ userError "something went wrong"

ex2 :: StateT Int IO ()
ex2 = do
    x <- get
    liftIO $ print x

ex3 :: StateT Int IO ()
ex3 = ex1 `onException` ex2

main :: IO ()
main = evalStateT ex3 0
Run Code Online (Sandbox Code Playgroud)

当我们运行程序时,我们得到以下输出。

$ runhaskell Test.hs
0
Test.hs: user error (something went wrong)
Run Code Online (Sandbox Code Playgroud)

但是,我预计输出如下。

$ runhaskell Test.hs
10
Test.hs: user error (something …
Run Code Online (Sandbox Code Playgroud)

haskell exception state-monad io-monad

5
推荐指数
1
解决办法
76
查看次数

为什么`filterM + mapM_` 比`mapM_ + when` 慢这么多,列表很大?

我不太了解 Haskell 优化在内部是如何工作的,但我一直在使用过滤器,希望它们被优化为与 C++ 中的简单 if 等效的东西。例如

mapM_ print $ filter (\n -> n `mod` 2 == 0) [0..10]
Run Code Online (Sandbox Code Playgroud)

将编译成相当于

for (int i = 0; i < 10; i++)
    if (i%2 == 0)
        printf("%d\n", i);
Run Code Online (Sandbox Code Playgroud)

对于长列表(10 000 000 个元素),基本列表似乎是正确的,filter但如果我使用 monadic ,则存在巨大差异filterM。我为此速度测试编写了一段代码,很明显,filterM使用when.

import Data.Array.IO
import Control.Monad
import System.CPUTime

main :: IO ()
main = do
  start <- getCPUTime
  arr <- newArray (0, 100) 0 :: IO (IOUArray Int Int)
  let
    okSimple i = …
Run Code Online (Sandbox Code Playgroud)

monads optimization performance haskell io-monad

5
推荐指数
1
解决办法
127
查看次数

Haskell IO Int和Int

我最近开始学习Haskell.我正在尝试编写一个选择数组的随机元素的程序:

import System.Random

randomInt :: (Int, Int) -> IO Int
randomInt range = randomRIO range :: IO Int

choseRandom :: [a] -> a
choseRandom list = 
    length list
    >>=
        (\l -> randomInt(0,l-1))
        >>=
            (\num -> (list !! num))

main :: IO ()
main = undefined
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Build FAILED

C:\Users\User\Haskell\Real\src\Main.hs: line 7, column 9:
  Couldn't match expected type `IO Int' with actual type `Int'

    In the return type of a call of `length'

    In the first argument of `(>>=)', namely `length …
Run Code Online (Sandbox Code Playgroud)

monads haskell types io-monad

4
推荐指数
2
解决办法
2894
查看次数

为什么类型在do块的下一行而不是在同一行匹配?

我正在从用户必须输入的输入中读取几行内容:

main :: IO ()
main = do
  let size = 3
  arr <- replicateM size getLine
  let pairs = map parsePair arr
  print pairs
Run Code Online (Sandbox Code Playgroud)

为什么我可以map parsePair arr在单独的行上做而不是在同一行上做,像这样:

arr <- map parsePair (replicateM size getLine)
Run Code Online (Sandbox Code Playgroud)

这样做,我得到了错误?:

• Couldn't match type ‘[]’ with ‘IO’
  Expected type: IO [Int]
    Actual type: [[Int]]
Run Code Online (Sandbox Code Playgroud)

为了给您更多细节,这里是parsePair

parsePair string = map parseInt $ words string

parseInt :: String -> Int
parseInt s = read s :: Int
Run Code Online (Sandbox Code Playgroud)

io monads haskell do-notation io-monad

4
推荐指数
2
解决办法
81
查看次数