如何解决使用组合函子的应用实例
我有两种形式的函数
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 _)
。真的有办法吗?
解决方法
我认为应用函子是组成的,因此我可以将应用实例用于组合函子。
是正确的,但是假设我们采用f ~ (->) Int
,则类型为(<$>) :: (a -> b) -> (Int -> a) -> (Int -> b)
和(<*>) :: (Int -> (a -> b)) -> (Int -> a) -> (Int -> b)
,但这与类型baz
不匹配需要String
和Integer
,而foo
返回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 = liftA2 baz <$> foo <*> bar
liftA2
将在这里将baz :: String -> Integer -> Float
转换为liftA2 baz :: IO String -> IO Integer -> IO Float
。因此,此函数然后与foo
和bar
的输出类型匹配。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。