标签: io-monad

Haskell Safe IO

我正在尝试编写一个简单的函数来安全地读取文件(如果存在),如果文件不存在则不执行任何操作:

safeRead :: String -> IO ()
safeRead path = readFile path `catch` handleExists
  where handleExists e
          | isDoesNotExistError e = return ()
          | otherwise = throwIO e
Run Code Online (Sandbox Code Playgroud)

这在编译时失败了

Couldn't match type ‘[Char]’ with ‘()’
Expected type: IO ()
  Actual type: IO String
In the first argument of ‘catch’, namely ‘readFile path’
In the expression: readFile path `catch` handleExists
Run Code Online (Sandbox Code Playgroud)

这是有道理:t readFilereadFile :: FilePath -> IO String.例如返回IO String(并且IO String不相同IO ())的函数

将签名更改为 …

io haskell types io-monad

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

如何在Haskell中专门针对IO使用mapM

说我有一个代表从一些计算任务kv其中一些投入必须要获取外部。

newtype Task k v = Task { run ? ? f. Monad f ? (k ? f v) ? f v }
Run Code Online (Sandbox Code Playgroud)

对于某些任务,mapM将使用例如提取多个密钥。我想专攻mapM一些单子。专门针对IO我想用来Control.Concurrent.Async.mapConcurrently同时执行IO操作的monad 。

我的第一个直觉是介绍包装器类型

newtype AsyncIO a = AsyncIO { io :: IO a }
Run Code Online (Sandbox Code Playgroud)

然后介绍

instance Monad AsyncIO
Run Code Online (Sandbox Code Playgroud)

但是,这是行不通的,因为在当前的GHC实现mapMtraverse,它是在中定义的Traversable

是否有一个优雅的解决方案?

monads haskell io-monad

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

haskell程序的灵活参数数量

我正在使用System.FilePath.Findfilemanip模块以递归方式查找我需要处理的所有文件(这里我将仅使用打印到控制台作为要执行的操作,以免混淆事物).现在,这段代码:

import System.Environment (getArgs)
import System.FilePath (FilePath)
import System.Directory (doesDirectoryExist, getDirectoryContents,doesFileExist)
import Control.Monad
import System.FilePath.Find (find,always,fileType,(==?),FileType(..),(&&?),extension)


main= do 
    [dbFile,input]<- getArgs
    files <- findFiles input
    mapM_ putStrLn files 
    return ()

searchExtension :: String
searchExtension = ".hs"

findFiles :: FilePath -> IO [String]
findFiles = find (always) ( fileType ==? RegularFile &&? extension ==? searchExtension)
Run Code Online (Sandbox Code Playgroud)

适合这个电话

./myprog tet.

在这种情况下,将get忽略该参数(稍后将是输出数据库文件),并且为匹配文件递归搜索第二个参数.它还允许我只指定一个文件,这是完美的!

但是,我希望能够指明

./myprog tet path1 path2 path4 file1

但这当然在模式匹配中失败了:

./myprog tet..

myprogt:用户错误(myprog.hs中的do表达式中的模式匹配失败:11:9-22)

现在,我如何使这个程序更灵活,以便我可以采取两个以上的参数?

很抱歉这个问题,但是我的Haskell知识是有限的,但是在我的第一个项目中我必须做的每件新事情都在增加.

haskell pattern-matching command-line-arguments io-monad

0
推荐指数
1
解决办法
118
查看次数

将一个IO递归循环重构为Haskell中的monad折叠

我写了一个tcp服务器,这是我的主循环方法:

serverLoop :: Socket -> IO ()
serverLoop sock = do
    (conn, _) <- accept sock
    forkIO $ handleConn conn
    serverLoop sock
Run Code Online (Sandbox Code Playgroud)

(注意:handleConn :: Socket -> IO ()是我的程序特有的功能.)

我想将它重构成更加一元的方式,这是我的试探性的:

serverLoop :: Socket -> IO ()
serverLoop sock = foldl1 (>>) $ map go $ repeat sock
     where go sock = (accept sock) >>= (forkIO . handleConn . fst) >> return ()
Run Code Online (Sandbox Code Playgroud)

但是,一旦我开始通过套接字发送数据,这会使程序崩溃.

以下是我的问题:为什么?有什么办法解决的?

sockets haskell network-programming io-monad

0
推荐指数
1
解决办法
159
查看次数

Haskell 中使用 monad 的 while 循环示例

我想使用 monad 在 haskell 中编写一个循环,但我很难理解这个概念。

有人可以为我提供一个简单的 while 循环示例,同时满足某些涉及 IO 操作的条件吗?我不想要一个抽象的例子,而是一个真正有效的具体例子。

monads haskell loops while-loop io-monad

0
推荐指数
1
解决办法
1408
查看次数

将随机生成的列表作为参数传递给Haskell

我是Haskell的新手,并且在整个IO事情上遇到了麻烦.

我试图找出遍历haskell列表所需的时间.我想生成一个随机数列表并将其作为参数传递给函数,以便我可以打印列表的每个元素.我正在使用CRITERION包作为基准.这是代码:

{-# LANGUAGE OverloadedStrings #-}
import System.Random
import Control.Exception
import Criterion.Main

printElements [] = return ()
printElements (x:xs) = do print(x)
                          printElements xs

randomList 0 = return []
randomList n = do
  x  <- randomRIO (1,100)
  xs <- randomList (n-1)
  return (x:xs)


main = defaultMain [
  bgroup "printElements" [ bench "[1,2,3]"  $ whnf printElements (randomList 10)
               , bench "[4,5,6]"  $ whnf printElements [4,5,6,4,2,5]
               , bench "[7,8,9]"  $ whnf printElements [7,8,9,2,3,4]
               , bench "[10,11,12]" $ whnf printElements [10,11, 12,4,5]
               ] …
Run Code Online (Sandbox Code Playgroud)

benchmarking haskell list haskell-criterion io-monad

0
推荐指数
1
解决办法
68
查看次数

如何在Haskell的IO monad中包装char文字?

我知道您应该将要对结果执行的操作包装在monad中,而不是从monad中拆包。

我找不到如何做到这一点的任何对白痴友好的例子。

例如,我想做这样的事情:

myFunction = do
    c <- getChar
    if (c == 'q')
        then putStrLn "take action 1"
        else putStrLn "take action 2"
Run Code Online (Sandbox Code Playgroud)

但是您不能直接将char文字与IO Char进行比较。

GHCi版本是8.4.4。

错误信息:

[2之1]编译Lib(/Users/jamesstrieter/hask-tink/src/Lib.hs,已解释)

/Users/jamesstrieter/hask-tink/src/Lib.hs:66:18:错误:•无法将预期类型'IO char'与实际类型'Char'匹配•在第二个参数'(==)' ,即“ q”在表达式中:x =='q'在'what2do'的等式中:what2do x = x =='q'•相关绑定包括x :: IO字符(绑定在/ Users / jamesstrieter /hask-tink/src/Lib.hs:66:9)what2do :: IO字符-> Bool(绑定到/Users/jamesstrieter/hask-tink/src/Lib.hs:66:1)| 66 | what2do x = x =='q'| ^^^失败,未加载任何模块。

monads haskell do-notation io-monad

0
推荐指数
2
解决办法
163
查看次数

无法将预期的类型“ IO [String]”与实际类型“ [String]”匹配

我有这两个代码段,我猜它们会做同样的事情,但事实并非如此。这是为什么?

这个很好用:

fdup :: String -> IO ()
fdup filename = do
        h <- openFile filename ReadMode
        c <- hGetContents h
        putStr $ unlines $ parse $ lines c
        hClose h
Run Code Online (Sandbox Code Playgroud)

这返回一个错误Couldn't match expected type ‘IO [String]’ with actual type ‘[String]’

fdup' :: String -> IO ()
fdup' filename = do
        h <- openFile filename ReadMode
        c <- hGetContents h
        ls <- lines c
        putStr $ unlines $ parse $ ls
        hClose h
Run Code Online (Sandbox Code Playgroud)

parse :: [String] -> [String] …

haskell io-monad

0
推荐指数
1
解决办法
67
查看次数

完全按照 Haskell 中的格式读取字符串

我的程序是这样的:

func = do
      text <- getLine
      return text
Run Code Online (Sandbox Code Playgroud)

如果我读 line \123\456,结果自然是\\123\\456. 我怎样才能得到 \123\456结果?

io haskell io-monad

0
推荐指数
1
解决办法
115
查看次数

如何在 Haskell 中打印列表的单个元素?

我是 Haskell 的初学者,我想知道是否可以打印给定列表的单个元素。我尝试解决这个问题,但失败了。这是代码:

main :: IO()
main = do
    let list = [1,2,3]
    let size = length list
    let temp = print_elem list size
    print temp


print_elem :: [Int] -> Int -> Int
print_elem xs x = do
    let size = length xs
    let idx = size - x
    let element = xs !! idx
    putStr (show element)
    putStr(" ")
    let dummy = print_elem (xs (x-1))
    return " "
Run Code Online (Sandbox Code Playgroud)

我想打印这样的东西

1 2 3
Run Code Online (Sandbox Code Playgroud)

如果我只是使用putStr (show list)它会显示[1,2,3],我不想要那样。 …

haskell functional-programming output io-monad

0
推荐指数
1
解决办法
84
查看次数