簡體   English   中英

Haskell:有時返回函數的函數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM