A - > IO B到IO(A - > B) [英] A -> IO B to IO (A -> B)
问题描述
我想转换一个函数 A - > IO B
到 IO(A - > B)
,知道只有有限数量的可能值 A
。目前我只是做
$ $ p $转换::(A-> IO B) IO(A→B)
转换f = do
b1 < - f a1
b2 < - f a2
...
let f' a1 = b1
f'a2 = b2
...
返回f'
然而,我并不满意这需要的代码量。
稍微提升版本Joachim的答案,它使用 Data.Map
更快地执行查找。
{ - #LANGUAGE TupleSections# - }
$ b $我将使用TupleSections编译指示。 b import Data.Map
import Control.Monad
为了增加整洁度,假设您的 Piece
类型可以给出 Ord
,有界
和 Enum
实例。
data Piece = Knight |主教| Rook派生(Ord,Bounded,Enum,Show)
并定义有用的枚举
函数
枚举::(有界a,枚举a)=> [a]
enumerate = [minBound..maxBound]
现在你可以做 p>
convert ::(Monad m,Bounded a,Enum a,Ord a)=> (a - > m b) - > m(a - > b)
convert f = do
memo< - sequence [liftM(a,)(f a)| a< - 枚举]
返回(fromList备忘录!)
I want to convert a function A -> IO B
to IO (A -> B)
, knowing that there is only a finite number of possible values of A
. At the moment I just do
convert :: (A -> IO B) -> IO (A -> B)
convert f = do
b1 <- f a1
b2 <- f a2
...
let f' a1 = b1
f' a2 = b2
...
return f'
However I'm not satisfied with the amount of code this requires.
A slightly souped-up version of Joachim's answer, that uses Data.Map
to perform the lookup faster. I'll be using the TupleSections pragma as well.
{-# LANGUAGE TupleSections #-}
import Data.Map
import Control.Monad
For added neatness, assume that your Piece
type can be given Ord
, Bounded
and Enum
instances.
data Piece = Knight | Bishop | Rook deriving (Ord,Bounded,Enum,Show)
and define the useful enumerate
function
enumerate :: (Bounded a, Enum a) => [a]
enumerate = [minBound..maxBound]
Now you can do
convert :: (Monad m, Bounded a, Enum a, Ord a) => (a -> m b) -> m (a -> b)
convert f = do
memo <- sequence [liftM (a,) (f a) | a <- enumerate]
return (fromList memo!)
这篇关于A - > IO B到IO(A - > B)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!