应用具有 Monadic 结果的函数,而不是具有非 Monadic 结果的函数

问题描述 投票:0回答:1

我有一个函数(来自库)接受另一个函数作为参数:

func :: ( a -> b ) -> a -> m()

但是现在,我想将一个生成 Monadic 结果的函数应用于

func
funcArg :: a -> m b

所以

func
实际上需要是
func :: ( a -> mb ) -> a -> m()

我有一种感觉,

func
可以提升为
m
,而得到的
m ( m() )
可以变成所需的
m()
。但我现在真的只是猜测。

我该怎么办?任何提示都将受到高度赞赏。

编辑: 我给出的类型签名不准确。应该是

func :: ( a -> b ) -> c -> m()
。具体签名是 Gloss
animate :: Display -> Color -> ( Float -> Picture ) -> IO()
中的 animate 函数。虽然我的函数有签名
( Float -> IO Picture )
。在这种情况下使用的正确函数是
animateIO

haskell
1个回答
0
投票

我是初学者,所以请不要相信我的话。经验丰富的 Haskellers 很可能会建议不要这样做。但既然你要求提示,这就是我的尝试。

首先,我检查了此类型检查:

func :: a -> b -> (Float -> c) -> IO ()
func = undefined

funcArg :: Float -> IO a
funArg = undefined

-- This seems to be essentially what is desired
transform :: (Float -> IO a) -> (Float -> a)
transform = undefined

-- So that a tranformed 'funcArg' can be plugged into 'func'
composed :: a -> b -> IO ()
composed x y = func x y (transform funcArg)

这个进行类型检查,所以问题变成了如何从单子动作中提取值。从这个链接的讨论来看,似乎没有通用的方法可以做到这一点。不同的 monad 将有其特定的方法(例如

fromMaybe
代表
Maybe
monad)。此外,在该线程中,有人建议从
unsafePerformIO
中选择
System.IO.Unsafe

如果您确定该操作的安全性,您可以这样做:

import System.IO.Unsafe (unsafePerformIO)

然后

transform f = \x -> unsafePerformIO (f x)

unsafePerformIO

文档
说:“为了安全起见,IO计算应该没有副作用并且独立于其环境。”您必须亲自检查一下。

我希望这有帮助。如果没有别的事,我希望类型检查练习能够帮助您找到您想要的东西。

© www.soinside.com 2019 - 2024. All rights reserved.