使用组合仿函数的应用实例
Using Applicative instance of composed functors
我有两个表单函数
foo :: Int -> IO String
bar :: Int -> IO Integer
基本上存在于由 (->) Int
和 IO
组成的函子中。
现在,具有类型
的功能
baz :: String -> Integer -> Float
我想使用
等应用语法将其提升到 Int -> IO _
上下文
foobarbaz :: Int -> IO Float
foobarbaz = baz <$> foo <*> bar
如果我这样做,编译器会用
对我大喊大叫
Couldn't match type `IO String' with `[Char]'
Expected type: Int -> String
Actual type: Int -> IO String
就好像它只是试图将应用程序实例用于 (->) Int
。
我认为应用仿函数是组合的,这样我就可以将应用实例用于组合仿函数。我错了吗?还是我应该向编译器提供更多信息?
我也尝试启用 TypeApplications
来明确指定我想使用的仿函数,但我意识到我不能写 (->) Int (IO _)
。真的有办法吗?
I thought applicative functors composed, so that I could use the applicative instance for the composed functor.
这是正确的,但是假设我们采用 f ~ (->) Int
,那么类型是 (<$>) :: (a -> b) -> (Int -> a) -> (Int -> b)
和 (<*>) :: (Int -> (a -> b)) -> (Int -> a) -> (Int -> b)
,但这与类型不匹配,因为 [=13] =] 需要一个 String
和一个 Integer
,而 foo
returns 一个 IO String
和 bar
一个 IO Integer
.
您可以利用 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
提升 baz
功能以使用 IO
操作的结果:
import Control.Applicative(liftA2)
foobarbaz :: Int -> IO Float
foobarbaz = <b>liftA2</b> baz <$> foo <*> bar
因此,liftA2
会将 baz :: String -> Integer -> Float
转换为 liftA2 baz :: IO String -> IO Integer -> IO Float
。因此,这是一个与 foo
和 bar
.
的输出类型相匹配的函数
我有两个表单函数
foo :: Int -> IO String
bar :: Int -> IO Integer
基本上存在于由 (->) Int
和 IO
组成的函子中。
现在,具有类型
baz :: String -> Integer -> Float
我想使用
等应用语法将其提升到Int -> IO _
上下文
foobarbaz :: Int -> IO Float
foobarbaz = baz <$> foo <*> bar
如果我这样做,编译器会用
对我大喊大叫Couldn't match type `IO String' with `[Char]'
Expected type: Int -> String
Actual type: Int -> IO String
就好像它只是试图将应用程序实例用于 (->) Int
。
我认为应用仿函数是组合的,这样我就可以将应用实例用于组合仿函数。我错了吗?还是我应该向编译器提供更多信息?
我也尝试启用 TypeApplications
来明确指定我想使用的仿函数,但我意识到我不能写 (->) Int (IO _)
。真的有办法吗?
I thought applicative functors composed, so that I could use the applicative instance for the composed functor.
这是正确的,但是假设我们采用 f ~ (->) Int
,那么类型是 (<$>) :: (a -> b) -> (Int -> a) -> (Int -> b)
和 (<*>) :: (Int -> (a -> b)) -> (Int -> a) -> (Int -> b)
,但这与类型不匹配,因为 [=13] =] 需要一个 String
和一个 Integer
,而 foo
returns 一个 IO String
和 bar
一个 IO Integer
.
您可以利用 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
提升 baz
功能以使用 IO
操作的结果:
import Control.Applicative(liftA2)
foobarbaz :: Int -> IO Float
foobarbaz = <b>liftA2</b> baz <$> foo <*> bar
因此,liftA2
会将 baz :: String -> Integer -> Float
转换为 liftA2 baz :: IO String -> IO Integer -> IO Float
。因此,这是一个与 foo
和 bar
.