回答
im trying to re-assign an existing variable
你不能在Haskell中做到這一點。你可以通過使用IORef
來完成某些事情,但這很少是問題的正確解決方案 - 當然不是初學者可能遇到的情況。
相反,您應該重新設計您的程序邏輯,以便它不需要可變變量的功能。
在這一點上,我懷疑有任何程序邏輯來重新設計。 OP只想知道如何處理Haskell中的其他語言。 –
Haskell是一個偉大的imperative語言,編寫可以重新分配狀態的程序是一個非常有趣的高級話題!這絕對不是你現在想要的方法,但有一天會回來
它需要一點努力去定義一個模擬全局可變變量的環境。然而,一旦你掌握了它,類型的精確性就變得非常方便了。
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Monad.State
大家都知道,大象是整數。
type Elephant = Integer
你想要一個程序,其全局可變狀態有一頭大象。首先讓我們來定義一下大象的含義。 Lens
很好地捕捉了這個概念。現在
class HasElephant a
where
elephant :: Lens' a Elephant
,我們可以定義function
,它分配一個新的價值elephant
。
function :: (MonadState s m, HasElephant s) => Elephant -> m()
function x =
elephant .= x
約束MonadState s m
和HasElephant s
都在說我們的程序必須能夠持有某種類型s
的可變狀態,類型s
必須有大象。
我們還定義一個打印大象的程序。
printElephant :: (MonadState s m, HasElephant s, MonadIO m) => m()
printElephant =
use elephant >>= (liftIO . print)
這個程序執行I/O(印刷),所以我們有一個附加的約束MonadIO m
,說我們的節目類型m
必須能夠做I/O。
非洲森林大象(Loxodonta cyclotis)是一種在剛果盆地發現的森林棲息物種。
data Congo = Congo
{ _congoElephant :: Elephant
}
makeLenses ''Congo
我們必須定義Congo
有一頭大象的方式。
instance HasElephant Congo
where
elephant = congoElephant
現在我們可以編寫一個示例程序。我們的程序將打印elephant
的值,然後更改elephant
的值,然後再次打印。
main' :: StateT Congo IO()
main' =
do
printElephant
function 2
printElephant
然後我們可以運行這個程序。
main :: IO()
main = Congo 0 & runStateT main' & void
輸出是:
0
2
雖然這些都是很好的事情要知道和使用一般,我覺得這可能不是最合適的時候談論'StateT',monad變壓器,類型和鏡頭......如果有人不知道這方面的哈斯克爾(沒有像C這樣的語言的方式賦值)並且以前沒有遇到過這種差異,我懷疑他們還沒有這方面的背景,甚至可能會嚇跑他們(我*可能*是錯的當然,但我有一個非常強烈的懷疑......)。 –
@DavidYoung我不指望我的答案會提供任何即時效用的提問者。其他人已經這樣做了。這個答案在這裏,因爲我一直相信,偶爾瞥見一些你還不能理解的東西是有價值的,從你腳下的路徑向上看,並注視着山上的雲彩形狀。 –
這是一個公平點。 –
Haskell是在函數式編程世界和函數式編程的領導者通常被稱爲「編程不分配。」這幾乎是功能編程的整個點不使用分配。一旦你使用它,你就不再以「功能」的方式來做它了。當然有時候,FP會盡量減少這些時間。
所以,要回答你的問題,「爲什麼不工作?」首先,語法不正確。 =
並不意味着在Haskell中賦值。它將一個名稱綁定到一個表達式。你不能這樣做兩次(在相同的範圍內)。換句話說,「變量」是不可變的(就像在數學中一樣)。其次,突變是一種副作用行爲,Haskell將這些行爲視爲必須在IO
世界中完成的不純行爲。
我可以告訴你如何實際上變異在Haskell中的引用,但我不認爲這就是你需要在這一點上。
到可變x
綁定到值v
最原始的方法是編寫的函數採取x
作爲參數,並傳遞給v
該功能。
這有時可以用來「模擬」可變變量的效果。
例如,勢在必行代碼
// sum 0..100
i = s = 0;
while (i <= 100) {
s = s+i;
i++;
}
return s;
成爲
final_s = f 0 0 -- the initial values
where
f i s | i <=100 = f (i+1) (s+i) // increment i, augment s
| otherwise = s // return s at the end
上面的代碼是不漂亮FP碼,但至少它是足夠接近的命令性代碼,使其能夠當場連接。
最後題外話:
當一個第一通知這一點,它通常是引誘到落入Blub paradox。人們可以很容易想到:「什麼!Haskell需要所有的東西來模擬一個簡單的任務?如果在語言Blub分配是微不足道的,並且模擬Haskell需要這麼多努力,那麼顯然Blub比Haskell好得多!」。這將是一個完美的Blub悖論案例:當一個Blub程序員轉向另一種語言時,他們立即察覺到Blub不能直接翻譯的內容,並且沒有注意到新語言的所有其他功能並不存在泡殼。 他們的思想現在在「Blub」中思考,它需要付出很大的努力才能適應新的模型。
幾乎與此相反,學習都 FP和命令式編程是有用的,因爲當僅用於其中的一種時,學習其他範式並非微不足道。如果他們之間的差距很小,那麼爲了解決同樣的問題而學習兩種接近的方法是不值得的。
一般來說這不起作用,因爲您通常會進行不可變的聲明,而不是指定一系列操作。你可以這樣做:
elephant = 3
main = print elephant
但你也可以這樣做:
main = print elephant
elephant = 3
由於代碼不指定執行順序,也沒有辦法解釋多項任務作爲不是錯誤以外的任何。
如果你想指定的一系列操作,使用做符號:
main = do
let elephant = 0
print elephant
let elephant = 1
print elephant
let elephant = 2
print elephant
在的代碼做塊順序執行,這樣可以有效地重新分配變量的方式,您可以在大多數編程語言中。
請注意,這段代碼實際上只是爲大象創建了一個新的綁定。舊的價值依然存在:
main = do
let elephant = 1
print elephant
let printElephant = print elephant
let elephant = 2
print elephant
printElephant
因爲printElephant功能我定義依然採用大象的舊值,這樣打印:
1
2
1
你確實可以做到這一點,但是強調'let elephant = 1'和'let elephant = 2'確實不**重新分配變量'elephant'很重要。相反,他們只是引入了一個_new_變量,該變量恰好也被稱爲'大象'。然後,「印象大象」選擇最近的一次出現(更確切地說,是_narrowest共享範圍內的那個),但在這個範圍之外,老大象始終保持相同的值。我建議這不應該在實際的Haskell代碼中完成(實際上'ghc-Wall'會警告它)。 – leftaroundabout
@leftaroundabout你說得對,我加了一點來說明不同之處。 此外,我知道這不是建議,但問題違背了語言所代表的一切。用一些可以推薦的東西很難回答這個問題。 –
- 1. MATLAB函數重新分配未定義數量的變量值
- 2. 在JQuery中爲變量分配函數
- 3. 如何在Lua中正確地重新分配變量?
- 4. 重新分配變量值
- 5. 在將結構傳遞給Matlab中的函數時重新分配變量
- 6. Haskell中的多變量函數
- 7. 如何將對象重新分配給python中的變量?
- 8. 重新分配函數變量上的JavaScript
- 9. 如何在函數中分配一個變量值? unix korn shell
- 10. Javascript:無法在遞歸函數調用中重新分配變量
- 11. python,在每個函數調用中停止變量重新分配?
- 12. 如何從一個定義函數內重新分配一個變量的值?
- 13. 如何在Haskell中重新實現「all」函數?
- 14. 將整數分配給Haskell中的變量
- 15. 如何將連鎖函數分配給jQuery中的變量
- 16. 如何重新分配一個新的有價值的變量
- 17. 如何將JavaScript函數中的變量的值分配給Mason變量?
- 18. 在r中的ifelse函數中分配變量
- 19. Python:返回函數變量並分配給新變量
- 20. 在包含的Dwoo模板中重新分配父變量
- 21. 如何在樹枝中分配變量?
- 22. 如何在VBA中分配變量?
- 23. 在函數參數中分配一個javascript變量的值?
- 24. JavaScript中的雙重變量分配
- 25. Haskell中的變量
- 26. 如何通過分配在FreeMarker的函數變量值
- 27. 強迫變量重新分配(Prolog)
- 28. 重新分配變量不起作用
- 29. 重新分配POST輸出變量
- 30. 重新分配變量列表
你要定義一個變量還是要重新 - 分配一個現有的變量?我在問,因爲你的例子看起來像你正試圖改變全局'elephant'變量的值。 – sepp2k
即時嘗試重新分配一個現有的變量。 – Fl4mer
在這兩種情況下,我認爲你正在擊中S.O.太快了,需要學習更多的語法和語言原語。我建議你通過閱讀來學習更多的Haskell。例如,[wikibooks](https://en.wikibooks.org/wiki/Haskell)和「函數式編程工藝」是開始的好地方。 –