我对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 !!
答案 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
内一样。