简体   繁体   English

将 IO 值转换为 haskell 函数

[英]IO values into haskell function

I currently have a function with definition:我目前有一个定义的函数:

f :: [Int] -> Int -> [[Int]]

And have two variables of type IO [Int] and IO Int.并且有两个类型为 IO [Int] 和 IO Int 的变量。 I want to pass these variables to this function f.我想将这些变量传递给这个函数 f。 I am able to do this when it is just one variable being passed to the function, but when it is 2 I can't get it to work.当只有一个变量被传递给函数时,我能够做到这一点,但是当它是 2 时,我无法让它工作。

You can write a do block:你可以写一个do块:

f' :: IO [[Int]]
f' = do
    x <- val1
    y <- val2
    return (f x y)

with val1 :: IO [Int] and val2 :: IO Int the values you want to pass as parameters.使用val1 :: IO [Int]val2 :: IO Int您想要作为参数传递的值。

or in an applicative style:或以应用风格:

f' :: IO [[Int]]
f' = f <$> val1 <*> val2

or we can make use of liftA2 :: (a -> b -> c) -> fa -> fb -> fc :或者我们可以使用liftA2 :: (a -> b -> c) -> fa -> fb -> fc

f' :: IO [[Int]]
f' = liftA2 f val1 val2

You should use <- in do notation and run the function on the unwrapped values.您应该在do符号中使用<-并在展开的值上运行该函数。

-- Implementations left out
xsFn :: IO [Int]
xFn :: IO Int

main = do
  xs <- xsFn
  x <- xFn
  -- We've unwrapped the values, so now xs :: [Int] and x :: Int

  let result = f xs x -- result :: [[Int]]
  -- do something with result
  return ()

IO has an Applicative instance, so you can use liftA2 : IO有一个Applicative实例,所以你可以使用liftA2

> f = undefined :: [Int] -> Int -> [[Int]]
> import Control.Applicative
> :t liftA2 f
liftA2 f :: Applicative f => f [Int] -> f Int -> f [[Int]]

With the TypeApplications extension, you can see it more clearly.通过TypeApplications扩展,您可以更清楚地看到它。

> :set -XTypeApplications
> :t liftA2 @IO f
liftA2 @IO f :: IO [Int] -> IO Int -> IO [[Int]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM