繁体   English   中英

Haskell function型带IO

[英]Haskell function type with IO

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

我有从数据库获取结果的 function 调用“func1”

类型定义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] -> 我已经创建,我想知道' funcWnt' function

谢谢!

作为一般观察:尝试始终考虑您的函数对输入的作用,假设它们已经得到它们。 您的函数似乎既关心获取输入又关心转换它们。 让他们只是转换,并使用一些外部 function 来获取他们的输入。

让我们看看我们是否可以采取您的想法,并按照这些新思路重新制定它:

你有:

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当然不做),那么用这种方式编写是非惯用的、笨拙的、非模块化的,并将所有纯代码放入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

最后,请注意我在每个顶级 function 上都放置了类型签名。 你也应该养成这样做的习惯。 它不仅有助于澄清你的意图(对你自己、其他开发人员,甚至是一周后的你自己),而且它消除了许多尴尬的类型注释,比如你必须放在func1中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM