我嘗試寫這需要一個數組和遍歷它的自定義函數返回,我需要打印每一個數字和遞歸推出相同的功能,但我得到的錯誤哈斯克爾,如何打印價值和功能
解析錯誤輸入'主
代碼:
firstitem n = if n /= [] n firstitem(tail n)
main = do
print(firstitem [1,2,3])
我嘗試寫這需要一個數組和遍歷它的自定義函數返回,我需要打印每一個數字和遞歸推出相同的功能,但我得到的錯誤哈斯克爾,如何打印價值和功能
解析錯誤輸入'主
代碼:
firstitem n = if n /= [] n firstitem(tail n)
main = do
print(firstitem [1,2,3])
您的第一個問題是您的語句錯誤if
。你應該寫
firstItem n = if {- condition-}
then {- do this -}
else {- do that -}
二,什麼功能firstItem
應該做的事,目前還不清楚。這聽起來像是它應該返回列表的第一項,但是您的描述看起來好像您要遍歷列表中的所有元素。
可以迭代和打印合併成一個單一的功能是這樣的:
printAll xs = if null xs -- If the list is empty
then return() -- then we're done, so we quit.
else do print (head xs) -- Otherwise, print the first element
printAll (tail xs) -- then print all the other elements.
main = printAll [1,2,3]
功能null
返回True
如果列表爲空,否則返回False
。語句return()
可以認爲是「沒有更多要處理的,所以現在停止該功能並返回任何結果」。第三行和第四行包含一個「do block」。 do塊基本上是一個膠水,它將兩個動作print (head xs)
和printAll (tail xs)
合併爲一個動作。你可以用花括號寫它,使它更清楚一點:
do {
print (head xs);
printAll (tail xs)
}
雖然你實際上並不需要他們 - 壓痕指定你的意思。
這解決了你的問題,但它有點笨重。畢竟Haskell應該是一門美麗的語言 - 所以我們讓你的代碼變得美麗!使用模式匹配將列表拖入其頭部和尾部會更好:
printAll [] = return()
printAll (x:xs) = do print x
printAll xs
這樣會好很多。但它可能更加模塊化。嘿,也許我們可以做一個通用的函數,它的動作作爲輸入,並執行該行動列表的每一個元素:
repeatedly f [] = return()
repeatedly f (x:xs) = do f x
repeatedly f xs
printAll xs = repeatedly print xs
這很好。但實際上,已經有一個功能可以做到這一點。這就是所謂的mapM_
(有一個很好的理由,它被稱爲這一點,但我不會進入現在)和它的Control.Monad
模塊:
import Control.Monad
printAll xs = mapM_ print xs
其實,你可以不用輸入這些xs
參數,編譯器可以推斷它應該在那裏:
printAll = mapM_ print
最後,你的代碼很漂亮。希望有點幫助。
非常感謝,非常詳細的解釋! – testCoder
「Control.Monad」的信息豐富和極好的介紹 –
在Haskell的if
總是需要有一個else
分支以及。您還錯過了then
,即您需要的形式爲if CONDITION then TRUE_VAL else FALSE_VAL
。
通過使用模式匹配,您可以完全避免if
。
要在執行過程中打印出進度,您可以使用Writer
monad。
我的問題有什麼不好?它完全定義。 – testCoder
我認爲在這個問題上*無法解釋的*降低了有點苛刻。 –
這個問題顯示了對Haskell基本概念的完全無知(在打印某個函數時沒有IO monad的跡象;對haskell的if-then-else語法和語義無知),而且缺乏常識:如果你想要要遞歸地打印某些東西,你需要將'print'放入遞歸函數中(即使對命令式程序員來說它也應該是顯而易見的)。 –