标签: io-monad

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
查看次数

在haskell程序中使用返回的EitherT

我正在尝试在我正在使用的Haskell项目中使用"citation-resolve"包,但是我无法在实际代码中使用EitherT.我知道他们是monad变形金刚,我想我明白这意味着什么,但我似乎无法真正弄清楚如何使用它们.代表我正在尝试做的玩具示例如下:

module Main where
import Text.EditDistance
import Text.CSL.Input.Identifier
import Text.CSL.Reference
import Control.Monad.Trans.Class 
import Control.Monad.Trans.Either 

main = do
    putStrLn "Resolving definition"
    let resRef = runEitherT $ resolveEither "doi:10.1145/2500365.2500595"
    case resRef of 
                Left e -> do 
                    putStrLn ("Got error: "++ e)
                Right ref -> do
                    putStrLn ("Added reference to database: "++ (show ref))
Run Code Online (Sandbox Code Playgroud)

这里resolveEither有类型:

resolveEither :: (HasDatabase s,
                  Control.Monad.IO.Class.MonadIO m,
                  mtl-2.1.3.1:Control.Monad.State.Class.MonadState s m)
                   => String -> EitherT String m Reference
Run Code Online (Sandbox Code Playgroud)

runEitherT $ resolveEither "ref"有类型:

runEitherT $ resolveEither "ref" …
Run Code Online (Sandbox Code Playgroud)

monads haskell monad-transformers either io-monad

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

如何在Spock请求处理程序中使用`IO String`?

我有以下函数生成1024的倍数的随机字符串:

import System.Random

rchars :: Int -> [IO Char]
rchars n = map (\_ -> randomRIO ('a', 'z')) [n | n <- [0..n]] -- a wasteful "iteration"-like func

rstr :: Int -> IO String
rstr n = sequence $ rchars (1024 * n)
Run Code Online (Sandbox Code Playgroud)

我想使用Spock将其暴露给Web,例如:

import Data.Monoid
import Data.Text
import Lib
import Web.Spock.Safe

main :: IO ()
main =
    runSpock 8080 $ spockT id $
    do get root $
           redirect "/data/1"
       get ("data" <//> var) $ \n ->
          do
           str <- …
Run Code Online (Sandbox Code Playgroud)

haskell io-monad haskell-spock

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

将(a - > IO b)转换为IO(a - > b)

我在IO上下文中有几种数据类型,如:

a :: IO String
b :: IO FilePath
c :: String -> IO String
Run Code Online (Sandbox Code Playgroud)

我想把它们放在一个数据对象中,如:

data Configdata = Configdata String FilePath (String -> String)
Run Code Online (Sandbox Code Playgroud)

因此,我不必从IO上下文中获取自己的每个值,而只是从中获取IO Configdata.

我没有解决方案的关键点是我如何转变String -> IO StringIO (String -> String).Hoogle没有给我任何能够做到这一点的功能.

我不确定它是否可能甚至不可能,因为函数的输入可能是无限的.

有人有解决方案或解释为什么不可能?我知道使用列表而不是函数是一个选项,但我更愿意使用函数.

monads haskell functional-programming lifting io-monad

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

在IO monad中进行递归

我一直试图弄清楚如何在IO monad中进行递归.我熟悉使用纯函数进行递归,但是无法将这些知识传递给IO monad.

使用纯函数递归
我很喜欢用纯函数进行递归,例如foo下面的函数.

foo (x:y:ys) = foo' x y ++ foo ys
Run Code Online (Sandbox Code Playgroud)

一个带有IO [String]输出
的函数我做了一个像goo下面这样的函数,它可以满足我的需求并具有IO输出.

goo :: String -> String -> IO [String]
goo xs ys = goo' xs ys 
Run Code Online (Sandbox Code Playgroud)

试图在IO monad中获取递归
当我尝试在IO monad中进行递归时(例如,"主"函数)我不能.我抬头一看liftM,replicateM和撤消最IO <-操作或功能.我想要一个IO monad hoo或者hoo'(为随后的乱码道歉).

hoo :: [String] -> IO [String]
hoo (xs:ys:yss) = do
                  let rs = goo xs ys ++ hoo yss
                  return rs
Run Code Online (Sandbox Code Playgroud)

要么

hoo' :: [String] -> IO [String]
hoo' …
Run Code Online (Sandbox Code Playgroud)

recursion haskell io-monad

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

cats-effect:如何将Map [x,IO [y]]转换为IO [Map [x,y]]

我有一个像这样的字符串到IO的映射Map[String, IO[String]],我想将其转换为IO[Map[String, String]].怎么做?

io scala io-monad scala-cats

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

什么(如果有的话)是最小化 IO Monad 对我的代码的影响的普遍接受的方式

我在 IO Monad 上有点挣扎。(仍然是 101 的学习者)

我相信我理解将“IO”与纯功能代码分离的绝佳理由,但这似乎使我的代码在使用时钟和环境属性时变得更加复杂。这是一个示例(与时钟相关):

timeZoneSeconds = liftA (60*) $ liftA timeZoneMinutes getCurrentTimeZone
Run Code Online (Sandbox Code Playgroud)

现在,我还有很多其他的东西与 timeZoneSeconds 相关——加、减、比较——在程序的其他地方,而且当 timeZoneSeconds 与其他位交互时,几乎我处理的所有事情都变成了“IO”,因此用liftAs填充我的代码。

所以基本上我看到我所有的纯代码都变成了 IO 脏代码。

在我看过的所有教学材料中,大部分关于 IO monad 的解释都是“读东西然后写东西”的一般类型,没有太多“计算东西”。

有没有推荐的方法来减少这种影响?

我是否应该重新定义我需要在“幕后”使用liftA 的所有操作符?

还是我应该继续下去?

haskell functional-programming io-monad

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

如何加入两个 Haskell IO monad

以下(工作)Haskell 程序输出随机拼写:

import System.Random

spells =
  [ "Abracadabra!"
  , "Hocus pocus!"
  , "Simsalabim!"
  ]

main :: IO()
main = do
  spell <- (spells !!) <$> randomRIO (0, length spells - 1)
  putStrLn spell
Run Code Online (Sandbox Code Playgroud)

然而,这个变量spell是非常无用的。它存储从法术列表中选择的随机字符串,但随后会立即传递给putStrLn函数并且不再使用。我尝试将两个 IO 操作合并为一行,如下所示:

main = putStrLn <$> (spells !!) <$> randomRIO (0, length spells - 1)
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

    • Couldn't match type ‘IO ()’ with ‘()’
      Expected type: Int -> ()
        Actual type: Int -> IO ()
    • In the first argument of ‘(<$>)’, …
Run Code Online (Sandbox Code Playgroud)

random monads haskell io-monad

3
推荐指数
2
解决办法
232
查看次数

在 GHCI 中映射 IO [Int]

我想知道如何IO [Int]在 GHCI 中映射一个。

?: :{
?| th :: IO [Int]
?| th = pure [1, 2, 3, 4]
?| :}
?: th
[1,2,3,4]
?: :t th
th :: IO [Int]
?: map (+2) th
    • Couldn't match expected type ‘[b]’ with actual type ‘IO [Int]’
    • In the second argument of ‘map’, namely ‘th’
      In the expression: map (+ 2) th
Run Code Online (Sandbox Code Playgroud)

想要的结果:

?: res = map (+2) th -- <-- some working version of this
?: res …
Run Code Online (Sandbox Code Playgroud)

haskell ghci io-monad

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

组合 IO 操作

我正在尝试编写一些 IO 包装的函数。

\n

我当前的代码(有效)是:

\n
getUserHome :: IO String\ngetUserHome = do\n    usr_id <- getRealUserID\n    homeDirectory <$> getUserEntryForID usr_id\n
Run Code Online (Sandbox Code Playgroud)\n

我正在寻找一种更方便的表示法(不使用 -do关键字的表示法)。

\n

没有任何 Monadic 沙拉我就写

\n
getUserHome = homeDirectory . getUserEntryForID . getRealUserID\n
Run Code Online (Sandbox Code Playgroud)\n

我猜想还有一个.尊重 Monad 的替代运算符..?但在我所有的寻找中,我还没有找到它。

\n
\n

我尝试过<$>,但这似乎不是我想要的:

\n
src/Main.hs:49:21: error:\n    \xe2\x80\xa2 Couldn\'t match type \xe2\x80\x98IO UserEntry\xe2\x80\x99 with \xe2\x80\x98UserEntry\xe2\x80\x99\n      Expected type: UserID -> UserEntry\n        Actual type: UserID -> IO UserEntry\n    \xe2\x80\xa2 In the second argument of \xe2\x80\x98(<$>)\xe2\x80\x99, namely \xe2\x80\x98getUserEntryForID\xe2\x80\x99\n      In the …
Run Code Online (Sandbox Code Playgroud)

haskell io-monad

3
推荐指数
2
解决办法
179
查看次数