带IO的Haskell函数类型

时间:2011-04-28 09:25:04

标签: haskell io monads

我对haskell中的一些东西感到困惑。首先我会清楚地解释我的问题,

我有函数调用“func1”,它取自DB的结果

类型定义 func1 :: IO[[String]]

func1 = do
 xx <- main --returns the sql output
 return (map (map fromSql) xx :: [[String]])

我需要编写两个函数,为我提供funcWnt :: IO[[String]] -> [[String]]funcWnt2 :: [String] -> Splice m

我在“funcWnt”中尝试了<-但是没有成功。可以告诉我怎么做这个吗?还是以其他方式做到这一点?'funcWnt2 :: [String] - &gt;我创建了,我想知道'funcWnt'功能

thnxxxx !!

1 个答案:

答案 0 :(得分:2)

作为一般观察:假设他们已经得到了它们,试着总是考虑你的功能对他们的输入做了什么。您的功能似乎与获取输入和转换它们有关。让他们转换,并使用一些外部函数来获取他们的输入。

让我们看看我们是否可以考虑你的想法,并按照这些新的方针重新制定它:

你有:

readDB :: IO [[SqlValue]]
readDB = ... -- not given here

func1 :: IO [[String]]
func1 = do
  xx <- readDB
  return (map (map fromSql) xx)

你现在想写一些改变它的东西。一种方法是复制你已经使用过的模式:

funcWnt :: IO [[String]]
  yy <- func1
  return ... -- some transformation of yy

funcWnt2 :: IO (Splice m)
  zz <- funcWnt
  return ... -- some transformation of zz into a Splice m

请注意,以func1样式编写的这些根本不是函数,而是IO中的值。如果这些函数没有IO,(而func1肯定没有),那么用这种方式编写是非惯用的,笨拙的,非模块化的,并将所有纯代码放在{{{ 1}}。相反,考虑纯粹写它们:

IO

现在您可以轻松地将它们组合在一起,并在一个func1 :: [[SqlValue]] -> [[String]] func1 = map (map fromSql) funcWnt :: [[String]] -> [[String]] funcWnt = ... -- some transformation funcWnt2 :: [[String]] -> Splice m funcWnt2 = ... -- some transformation into a Splice m 值中使用它们:

IO

或许,或许更具惯用性(不要害怕dbToSplice :: IO (Splice m) dbToSplice = do xx <- readDB return $ (funcWnt2 . funcWnt . func1) xx ,尽早学习):

>>=

现在,如果仅仅为了论证,dbToSplice :: IO (Splice m) dbToSplice = readDB >>= return . funcWnt2 . funcWnt . func1 需要在funcWnt2中做一些事情。然后定义如下:

IO

最后,请注意我在每个顶级函数上都放置了类型签名。你应该养成这样做的习惯。它不仅有助于澄清你的意图(对你自己,其他开发人员,甚至一周后你自己),但它消除了许多尴尬的类型注释,就像你必须放在funcWnt2 :: [[String]] -> IO (Splice m) funcWnt2 zz = do ... -- compute something with zz return ... -- returning some Splice m dbToSplice :: IO (Splice m) dbToSplice = readDB >>= funcWnt2 . funcWnt . func1 内一样。