Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 使用复合函子的应用实例_Haskell_Applicative - Fatal编程技术网

Haskell 使用复合函子的应用实例

Haskell 使用复合函子的应用实例,haskell,applicative,Haskell,Applicative,我有两个函数的形式 foo::Int->IO字符串 条::Int->IO整数 它们基本上存在于由(>)Int和IO组成的函子中。 现在,有一个类型的函数 baz::String->Integer->Float 我想使用如下应用程序语法将其提升到Int->IO\ucode>上下文 foobarbaz::Int->IO浮点 foobarbaz=baz foo bar 如果我这样做,编译器会对我大喊大叫 Couldn't match type `IO String' with `[Char]'

我有两个函数的形式

foo::Int->IO字符串
条::Int->IO整数
它们基本上存在于由
(>)Int
IO
组成的函子中。 现在,有一个类型的函数

baz::String->Integer->Float
我想使用如下应用程序语法将其提升到
Int->IO\ucode>上下文

foobarbaz::Int->IO浮点
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
需要
字符串和
整数,而
foo
返回一个
IO字符串
bar
一个
IO整数

您可以利用提升
baz
功能来使用
IO
操作的结果:

import Control.Applicative(liftA2)

foobarbaz :: Int -> IO Float
foobarbaz = liftA2 baz <$> foo <*> bar
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
的输出类型相匹配的函数,谢谢!这是有道理的,基本上我需要一次提升一个函子。我还可以做
(liftA2(liftA2-baz))foo-bar
。编译器不能只用一次提升就完成它有什么具体原因吗?@marcosh:有一次提升可以提升
(>Int)
,但还有一次提升可以提升
IO
。但是你是对的,你可以使用
liftA2(lifta2baz)foobar
。提升总是提升到“一个”应用级别之上(由于类型系统,它总是最外层)。因此,它不会“递归”到更多级别,因为这可能会导致歧义。@marcosh要在一次提升中完成此操作,您可以使用
Data.Functor.compose
显式地组合函子,但要付出一些新类型包装/展开的代价。