What is the equivalent formulation of a while loop in Haskell?

Being very new to Haskell, I'm wondering how to 1) calculate something until a certain criterion is met, and then 2) return the calculated value.

In languages ​​I know, you would use a while loop for this. How do you do it in Haskell?

+3


source to share


3 answers


You have to use recursion:

func :: <function type>
func <arguments> = 
    if condition 
        then <recursive call>
        else computedValue

      



There are other utilities that you will discover in the future, for example until

, that will help you with this. In the end, it really depends on the semantics of the loop and the condition. For example, if the condition is just "until it reaches the end of the list," you can simply use map

either one of the fold

-family functions .

+12


source


The answer is recursion. To give a pedantic example:

In Python:

def fib(n):
    a = 0
    b = 1
    while n > 0:
        a, b = b, a + b
        n -= 1
    return b

      

In Haskell:

fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)

      

Or equivalent without pattern matching

fib n = if n == 0 || n == 1 then 1 else fib (n - 1) + fib (n - 2)

      



Or more efficiently

-- the local variable fibs is an infinite list of all Fibonacci numbers
fib n = fibs !! n where fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

      

If you want to do something like reading text from STDIN

until you get a string that reads q

, then the easiest way is something like

import Control.Monad (unless)

prompt :: IO ()
prompt = do
    -- get input from user
    l <- getLine
    -- unless will execute its block if the condition is False
    unless (l == "q") $ do
        -- echo back to the user
        putStrLn $ "You entered: " ++ l
        prompt  -- recursive step here

      

Or in Python

def prompt():
    l = input()
    while l != "q":
        # Assuming Python 3
        print("You entered: " + l)
        l = input()

      

+5


source


Haskell has no built-in equivalent while

for stateful looping .

Instead, you usually

  • use a map

    family of functions on a range of values ​​to create a new range of values
  • use a filter

    family of functions on a range of values ​​to create a new subset of that range subject to certain conditions
  • use a fold

    family of functions to aggregate anything in this range
  • use recursion to do what you want (except for mutating input, of course).

...

Of course, Haskell and the libraries provide functions to make your life easier, but while loops while

can be considered idiomatic / "first class" in imperative languages, which is idiomatic / "first class" in Haskell (and other functional programming languages) is recursion. display, filtering and bending.

+4


source







All Articles