Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Haskell Dictionary
  3. lambda

lambda

In Haskell, a lambda expression (anonymous function) lets you define a function inline without giving it a name. You write a backslash (\) followed by the parameters, then ->, then the body expression — for example, \x -> x + 1. Lambda expressions are especially useful when passing short logic to higher-order functions like map, filter, and foldr, or when you need a one-off transformation and a named function would be overkill.

Syntax

-- -----------------------------------------------
--  Basic lambda expression syntax
-- -----------------------------------------------

-- Write an anonymous function inline using \parameter -> expression
-- \x -> x + 1          takes x and returns x + 1
-- \x -> x * 2          takes x and returns x * 2
-- \x -> x ++ "!"       appends "!" to a string and returns the result

-- -----------------------------------------------
--  Lambda expressions with multiple parameters
-- -----------------------------------------------

-- You can list multiple parameters after the backslash
-- \x y -> x + y        takes x and y and returns their sum
-- \name rank -> "[" ++ rank ++ "] " ++ name

-- -----------------------------------------------
--  Binding a lambda expression to a variable
-- -----------------------------------------------

-- A lambda expression is a value and can be bound to a variable
-- This is completely equivalent to a regular function definition
-- addOne :: Int -> Int
-- addOne = \x -> x + 1   -- binds \x -> x + 1 to addOne

-- -----------------------------------------------
--  Passing a lambda to a higher-order function (most common use)
-- -----------------------------------------------

-- Pass a lambda to map to transform every element
-- map (\x -> x * 10) [1, 2, 3]   -- [10, 20, 30]

-- Pass a lambda to filter to keep only matching elements
-- filter (\x -> x > 5) [3, 7, 2, 9, 4]   -- [7, 9]

-- -----------------------------------------------
--  Pattern matching on a tuple in a lambda parameter
-- -----------------------------------------------

-- You can pattern match in the parameter position: \(a, b) -> a + b
-- map (\(name, score) -> name ++ ": " ++ show score) pairs

Syntax reference

SyntaxDescription
\x -> exprA lambda expression (anonymous function) that takes parameter x.
\x y -> exprA lambda expression with two parameters x and y. It is curried.
\(a, b) -> exprA lambda expression that takes a tuple and pattern matches it inline.
f = \x -> exprBinds a lambda expression to the variable f. Equivalent to a regular function definition.
map (\x -> expr) xsApplies a lambda expression to every element of a list.
filter (\x -> cond) xsKeeps only the elements that satisfy the condition.
foldr (\x acc -> expr) z xsFolds a list from the right using an accumulator acc.

Sample code

pp_lambda_basic.hs
-- pp_lambda_basic.hs — demonstrates lambda expression basics: definition, variable binding, and passing to higher-order functions
-- Uses PSYCHO-PASS characters to show the \x -> expr syntax
-- and how to pass lambdas to map and filter
--
--   Compile and run:
--     ghc pp_lambda_basic.hs -o pp_lambda_basic && ./pp_lambda_basic

module Main where

-- -----------------------------------------------
--  Sample data (name and crime coefficient)
-- -----------------------------------------------
-- List of (Inspector/Enforcer name, crime coefficient) pairs
inspectors :: [(String, Int)]
inspectors =
  [ ("Tsunemori Akane",    12)    -- Inspector — coefficient is always low
  , ("Ginoza Nobuchika",   41)    -- Inspector — calm and collected
  , ("Kogami Shinya",     136)    -- Enforcer — former detective
  , ("Masaoka Tomomi",    116)    -- Enforcer — veteran
  , ("Kagari Shusei",      87)    -- Enforcer — youngest member
  ]

-- -----------------------------------------------
--  Binding a lambda to a variable (equivalent to a regular function)
-- -----------------------------------------------

-- Adds the enforcement threshold (100) to a crime coefficient to compute an "alert level"
-- Regular definition:  addThreshold x = x + 100
-- Bound lambda:        addThreshold = \x -> x + 100
addThreshold :: Int -> Int
addThreshold = \x -> x + 100    -- binds the lambda to addThreshold

-- Prepends an "[Enforcer]" tag to a name
tagEnforcer :: String -> String
tagEnforcer = \name -> "[Enforcer] " ++ name   -- binds the lambda to tagEnforcer

-- -----------------------------------------------
--  Using map with a lambda to transform every element
-- -----------------------------------------------

-- Multiplies each crime coefficient by 10 to produce a "potential risk" list
-- Lambdas are handy for short transformation functions like this
potentialRisks :: [(String, Int)]
potentialRisks = map (\(name, cc) -> (name, cc * 10)) inspectors
-- \(name, cc) -> pattern matches the tuple inline

-- Extracts just the names into a list
names :: [String]
names = map (\(name, _) -> name) inspectors
-- _ discards the unused element

-- -----------------------------------------------
--  Using filter with a lambda to select elements
-- -----------------------------------------------

-- Selects characters whose crime coefficient is >= 100 (enforcement level)
enforcers :: [(String, Int)]
enforcers = filter (\(_, cc) -> cc >= 100) inspectors

-- Selects characters whose crime coefficient is < 100 (inspector level)
clearInspectors :: [(String, Int)]
clearInspectors = filter (\(_, cc) -> cc < 100) inspectors

-- -----------------------------------------------
--  Output helper
-- -----------------------------------------------
printEntry :: (String, Int) -> IO ()
printEntry (name, cc) =
  putStrLn $ padRight 22 name ++ "  Crime coefficient: " ++ show cc
  where
    padRight n s = s ++ replicate (max 0 (n - length s)) ' '

-- -----------------------------------------------
--  Entry point
-- -----------------------------------------------
main :: IO ()
main = do
  putStrLn "===== All characters ====="
  mapM_ printEntry inspectors

  putStrLn ""
  putStrLn "===== Using a lambda bound to a variable ====="
  -- Applies addThreshold to each crime coefficient
  let thresholdList = map (\(name, cc) -> (name, addThreshold cc)) inspectors
  mapM_ printEntry thresholdList

  putStrLn ""
  putStrLn "===== map: potential risk (coefficient × 10) ====="
  mapM_ printEntry potentialRisks

  putStrLn ""
  putStrLn "===== filter: enforcement level (coefficient >= 100) ====="
  mapM_ printEntry enforcers

  putStrLn ""
  putStrLn "===== filter: clear status (coefficient < 100) ====="
  mapM_ printEntry clearInspectors
ghc pp_lambda_basic.hs -o pp_lambda_basic && ./pp_lambda_basic
[1 of 1] Compiling Main             ( pp_lambda_basic.hs, pp_lambda_basic.o )
Linking pp_lambda_basic ...
===== All characters =====
Tsunemori Akane         Crime coefficient: 12
Ginoza Nobuchika        Crime coefficient: 41
Kogami Shinya           Crime coefficient: 136
Masaoka Tomomi          Crime coefficient: 116
Kagari Shusei           Crime coefficient: 87

===== Using a lambda bound to a variable =====
Tsunemori Akane         Crime coefficient: 112
Ginoza Nobuchika        Crime coefficient: 141
Kogami Shinya           Crime coefficient: 236
Masaoka Tomomi          Crime coefficient: 216
Kagari Shusei           Crime coefficient: 187

===== map: potential risk (coefficient × 10) =====
Tsunemori Akane         Crime coefficient: 120
Ginoza Nobuchika        Crime coefficient: 410
Kogami Shinya           Crime coefficient: 1360
Masaoka Tomomi          Crime coefficient: 1160
Kagari Shusei           Crime coefficient: 870

===== filter: enforcement level (coefficient >= 100) =====
Kogami Shinya           Crime coefficient: 136
Masaoka Tomomi          Crime coefficient: 116

===== filter: clear status (coefficient < 100) =====
Tsunemori Akane         Crime coefficient: 12
Ginoza Nobuchika        Crime coefficient: 41
Kagari Shusei           Crime coefficient: 87
pp_lambda_multi.hs
-- pp_lambda_multi.hs — demonstrates multi-parameter lambda expressions and using lambdas with foldr
-- Uses PSYCHO-PASS characters to show the \x y -> expr form
-- and how to pass a lambda to foldr
--
--   Compile and run:
--     ghc pp_lambda_multi.hs -o pp_lambda_multi && ./pp_lambda_multi

module Main where

-- -----------------------------------------------
--  Sample data
-- -----------------------------------------------
-- List of (name, crime coefficient, psychological stability 0–100)
profiles :: [(String, Int, Int)]
profiles =
  [ ("Tsunemori Akane",    12,  98)   -- extremely stable
  , ("Ginoza Nobuchika",   41,  72)   -- slightly unstable
  , ("Kogami Shinya",     136,  45)   -- unstable
  , ("Masaoka Tomomi",    116,  53)   -- unstable
  , ("Kagari Shusei",      87,  61)   -- average
  ]

-- -----------------------------------------------
--  Lambda expression with multiple parameters
-- -----------------------------------------------

-- Calculates a "threat score" from a crime coefficient and stability value
-- Takes two arguments using the form \cc stability -> cc * 2 - stability
calcThreat :: Int -> Int -> Int
calcThreat = \cc stability -> cc * 2 - stability
-- For Kogami: 136 * 2 - 45 = 227

-- Takes a name and crime coefficient and returns a formatted display string
formatLine :: String -> Int -> String
formatLine = \name cc -> padRight 22 name ++ "  Coeff: " ++ show cc
  where
    padRight n s = s ++ replicate (max 0 (n - length s)) ' '

-- -----------------------------------------------
--  Using foldr with a lambda to aggregate and rebuild a list
-- -----------------------------------------------

-- Sums the crime coefficients of all entries using foldr
-- Uses \(_, cc, _) acc -> cc + acc to process each element and accumulator
totalCriminalCoeff :: [(String, Int, Int)] -> Int
totalCriminalCoeff = foldr (\(_, cc, _) acc -> cc + acc) 0

-- Builds a list of names whose threat score is >= 100 using foldr
-- This combines the effect of filter + map in a single foldr pass
highThreatNames :: [(String, Int, Int)] -> [String]
highThreatNames = foldr step []
  where
    -- step receives each element and the accumulator
    step (name, cc, stability) acc
      | calcThreat cc stability >= 100 = name : acc   -- high threat: prepend the name
      | otherwise                      = acc           -- low threat: skip

-- -----------------------------------------------
--  Output helper
-- -----------------------------------------------
printProfile :: (String, Int, Int) -> IO ()
printProfile (name, cc, stability) =
  putStrLn $ padRight 22 name
          ++ "  Coeff: "    ++ padLeft 3 (show cc)
          ++ "  Stability: "  ++ padLeft 3 (show stability)
          ++ "  Threat score: " ++ show (calcThreat cc stability)
  where
    padRight n s = s ++ replicate (max 0 (n - length s)) ' '
    padLeft  n s = replicate (max 0 (n - length s)) ' ' ++ s

-- -----------------------------------------------
--  Entry point
-- -----------------------------------------------
main :: IO ()
main = do
  putStrLn "===== All profiles (with threat score) ====="
  -- Uses the multi-parameter lambda calcThreat to display threat scores
  mapM_ printProfile profiles

  putStrLn ""
  putStrLn "===== foldr: sum of crime coefficients ====="
  let total = totalCriminalCoeff profiles
  putStrLn $ "  Total crime coefficient: " ++ show total

  putStrLn ""
  putStrLn "===== foldr: members with threat score >= 100 ====="
  let highThreat = highThreatNames profiles
  mapM_ (\name -> putStrLn $ "  " ++ name) highThreat

  putStrLn ""
  putStrLn "===== Passing a multi-parameter lambda directly to map ====="
  -- To use \name cc -> ..., you need currying
  -- Here a tuple lambda is passed to map instead
  let lines_ = map (\(name, cc, _) -> formatLine name cc) profiles
  mapM_ putStrLn lines_
ghc pp_lambda_multi.hs -o pp_lambda_multi && ./pp_lambda_multi
[1 of 1] Compiling Main             ( pp_lambda_multi.hs, pp_lambda_multi.o )
Linking pp_lambda_multi ...
===== All profiles (with threat score) =====
Tsunemori Akane         Coeff:  12  Stability:  98  Threat score: -74
Ginoza Nobuchika        Coeff:  41  Stability:  72  Threat score: 10
Kogami Shinya           Coeff: 136  Stability:  45  Threat score: 227
Masaoka Tomomi          Coeff: 116  Stability:  53  Threat score: 179
Kagari Shusei           Coeff:  87  Stability:  61  Threat score: 113

===== foldr: sum of crime coefficients =====
  Total crime coefficient: 392

===== foldr: members with threat score >= 100 =====
  Kogami Shinya
  Masaoka Tomomi
  Kagari Shusei

===== Passing a multi-parameter lambda directly to map =====
Tsunemori Akane         Coeff: 12
Ginoza Nobuchika        Coeff: 41
Kogami Shinya           Coeff: 136
Masaoka Tomomi          Coeff: 116
Kagari Shusei           Coeff: 87

Overview

A Haskell lambda expression is an anonymous function written as \x -> x + 1. The backslash (\) is meant to resemble the Greek letter lambda (λ). Because a lambda expression is a value, you can bind it to a variable or pass it directly as an argument to a higher-order function. The regular function definition f x = expr and the lambda binding f = \x -> expr are completely equivalent. To accept multiple parameters, list them after the backslash: \x y -> x + y. This is curried, meaning it is identical to \x -> \y -> x + y. When the argument is a tuple, you can pattern match it inline: \(a, b) -> a + b. The most common use of lambda expressions is passing short transformation, filtering, or aggregation logic directly to higher-order functions such as map, filter, and foldr. They are particularly convenient for temporary functions that are not important enough to deserve their own name. For an overview of higher-order functions, see Higher-order functions (map / filter / foldr). For function composition syntax, see Function composition (. and $).

If you find any errors or copyright issues, please .