A - > IO B到IO(A - > B) [英] A -> IO B to IO (A -> B)

查看:125
本文介绍了A - > IO B到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 - &gt; IO B到IO(A - > B)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆