[英]Haskell: Functions that sometimes return a function
你如何編寫一個可以返回值或其他函數的函數?
例如:
Function Foo (x)
If X = 0 Return "Done"
Else Return a Function that calls Foo(x-1)
在haskell中,函數的返回類型只能依賴於其參數的類型,並且在具有多態返回類型的函數的情況下,如何使用返回值。 特別是函數的返回類型不能取決於參數的值。
換句話說:你不能直接做你想做的事。 在要返回兩種類型的一種情況下,你通常可以在類型Either ab
定義為data Either ab = Left a | Right b
data Either ab = Left a | Right b
,它允許你返回類型的值, a
包裹在Left
或類型的值b
包裹在Right
。 然后,您可以使用模式匹配以類型安全的方式檢索值。
但是,因為在這種情況下, b
的類型必須是無限的,這不起作用,你必須為此定義自己的包裝器類型。 像這樣:
data MyResult = Str String | Fun ( () -> MyResult)
foo 0 = Str "done"
foo x = Fun (\ () -> foo (x-1))
foo
現在有類型Num a => a -> MyResult
。 但是每當你調用foo
你必須進行模式匹配,看看是否有一個帶有字符串的Str或者帶有函數的Fun。
還要注意,如果你想返回一個函數而不是一個值來延遲執行,這在haskell中沒有意義,因為它是懶惰的,並且在使用之前通常不會對它們進行評估。
從偽代碼的外觀來看,我猜你期望返回一個“無效”函數,即不帶參數的函數,並在調用時調用'Foo(x-1)'。
如果是這樣,那么正如sepp2k的答案結束時指出的那樣,Haskell中存在這樣的需求 - 這就是默認情況下會發生的事情。 特別:
foo x = if x == 0 then "Done"
else foo(x-1)
正是這樣做的:通過調用,也就是說,返回的值foo(7)
是一件事程序需要時,它的價值將評估foo(6)
在if
表達式的求值中不會評估遞歸調用。
你需要考慮函數的類型:如果Foo是類型(Int - > t),那么t是什么? 在兩種情況下都需要返回t類型的東西。 我認為這有點難,因為我不認為在同一個函數中可以是String類型或函數類型( - >)。
我知道這不會直接回答你的問題,但我認為你需要擴展你對“返回一個函數”意味着什么的想法。 例如功能:
mean3 :: Float -> Float -> Float -> Float
mean3 x y z = (x + y + z) / 3
可以被認為是“取3個數字並返回一個數字”。 或者它可以被認為是“一個函數取兩個數字,並將一個函數從一個數字返回一個數字”:
mean3 :: Float -> Float -> (Float -> Float)
mean1 :: (Float -> Float)
mean1 = mean3 1 2
剛剛接受sepp2k的好回答。 我認為你在Haskell中缺少一個基本概念 - 你總是返回一個函數。 甚至各種各樣的“價值”也是一種功能。
例如,胸圍打開ghci並嘗試:
> :t 5
:: (Num t) => t
只是一個不輸入的函數,返回值是一個Num。
> :t "What is this?"
:: [Char]
同樣,只是一個沒有值的函數,返回[Char]
“但這些都只是價值觀!我不相信!”
那么主要的是什么? (假設你已定義):
> :t main
:: IO ()
只是一個返回IO()實例的函數。
{-# LANGUAGE ExistentialQuantification #-}
data MyResult = Str String | forall a. Fun a -- deriving Show
foo 0 = Str "done"
foo x = Fun (\ () -> foo (x-1))
那種工作,但你不能導出一個存在類型(methinks)所以你需要像這樣調用foo: (\\(Main.Str x) -> x) (Main.foo 0)
。
如果你知道如何讓主模塊成為ghci的焦點,請發表評論。
通常,我們將其寫為
foo _ = "Done"
或者,毫無意義地,
foo = const "Done"
(當然,除非我們真的想得到負數的_|_
;-)
foo x =
if x<=0 then "Done"
else foo2 (x)
foo2 x = foo (x-1) ++ foo (x-1)
找到了一個非平凡的例子。 這似乎有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.