Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Haskell Syntax #278

Open
qingquan-li opened this issue Oct 27, 2024 · 0 comments
Open

Haskell Syntax #278

qingquan-li opened this issue Oct 27, 2024 · 0 comments

Comments

@qingquan-li
Copy link
Owner

Haskell is a statically typed, purely functional programming language known for its expressive syntax and powerful type system. Haskell's syntax emphasizes clarity and mathematical precision. Functions and immutability are at the heart of Haskell.

References:


1. Basic Structure of a Haskell Program

Every Haskell program consists of functions and definitions organized within modules.

-- This is a simple Haskell program
module Main where

main :: IO ()
main = putStrLn "Hello, World!"
  • Modules: Code is organized into modules using the module keyword.
  • Main Function: The main function is the entry point of a Haskell program.
  • Type Signatures: main :: IO () specifies that main is an IO action returning nothing (()).

2. Comments

  • Single-line Comments: Begin with --.

    -- This is a single-line comment
  • Multi-line Comments: Enclosed between {- and -}.

    {-
      This is a
      multi-line comment
    -}

3. Variables and Functions

  • Variable Definitions: Assigned using =.

    greeting :: String
    greeting = "Hello, Haskell!"
  • Function Definitions: Also use =, with parameters specified after the function name.

    add :: Int -> Int -> Int
    add x y = x + y
  • Type Signatures: Optional but recommended for clarity.

    double :: Num a => a -> a
    double x = x * 2
    • Num a => means for any type a that is an instance of the Num class.

4. Function Application

  • Syntax: Functions are applied by placing arguments after the function name, separated by spaces.

    result = add 5 3  -- result is 8
  • Parentheses: Used to group expressions.

    result = double (add 2 3)  -- result is 10

5. Operators

  • Arithmetic Operators: +, -, *, /, ^ (exponentiation), div, mod.
  • Comparison Operators: ==, /=, <, >, <=, >=.
  • Logical Operators: && (and), || (or), not.

6. Conditional Expressions

  • Haskell uses if expressions rather than statements.
    maxOfTwo :: Int -> Int -> Int
    maxOfTwo x y = if x > y then x else y

7. Lists

  • Creating Lists:

    numbers = [1, 2, 3, 4, 5]
  • List Operations:

    • Concatenation: ++
      combined = [1, 2, 3] ++ [4, 5]  -- [1,2,3,4,5]
    • Cons Operator: :, adds an element to the front.
      extended = 0 : numbers  -- [0,1,2,3,4,5]
  • Ranges:

    oneToTen = [1..10]
    evenNumbers = [2,4..20]  -- Step of 2
  • List Comprehensions:

    squares = [ x * x | x <- [1..5] ]  -- [1,4,9,16,25]

8. Tuples

  • Fixed-size collections that can hold different types.

    person :: (String, Int)
    person = ("Alice", 30)
  • Accessing tuple elements using pattern matching.

    getName (name, _) = name

9. Pattern Matching

  • Define functions by specifying patterns.

    factorial :: Int -> Int
    factorial 0 = 1
    factorial n = n * factorial (n - 1)
  • Pattern matching can be used in function parameters, case expressions, and let bindings.

10. Guards

  • Used to choose between different function definitions based on Boolean expressions.
    absolute :: Int -> Int
    absolute x
      | x < 0     = -x
      | otherwise = x

11. Where Clauses

  • Define local variables or functions.
    bmi :: Double -> Double -> String
    bmi weight height
      | bmiValue <= 18.5 = "Underweight"
      | bmiValue <= 25.0 = "Normal"
      | bmiValue <= 30.0 = "Overweight"
      | otherwise        = "Obese"
      where bmiValue = weight / (height ^ 2)

12. Let Expressions

  • Similar to where, but can be used wherever expressions are allowed.
    cylinder :: Double -> Double -> Double
    cylinder r h =
      let sideArea = 2 * pi * r * h
          topArea  = pi * r ^ 2
      in sideArea + 2 * topArea

13. Case Expressions

  • Provides pattern matching in expressions.
    describeList :: [a] -> String
    describeList xs = case xs of
      []      -> "The list is empty."
      [x]     -> "The list has one element."
      (x:xs)  -> "The list has multiple elements."

14. Higher-Order Functions

  • Functions that take other functions as arguments or return them.
    applyTwice :: (a -> a) -> a -> a
    applyTwice f x = f (f x)

15. Lambda Functions

  • Anonymous functions using \ syntax.
    incrementAll :: [Int] -> [Int]
    incrementAll xs = map (\x -> x + 1) xs

16. Type Classes and Instances

  • Type Classes: Define a set of functions that can be implemented by types.

    class Eq a where
      (==) :: a -> a -> Bool
      (/=) :: a -> a -> Bool
  • Instances: Implement a type class for a specific type.

    instance Eq Bool where
      True  == True  = True
      False == False = True
      _     == _     = False

17. Data Types

  • Define custom data types using data.

    data Shape = Circle Float | Rectangle Float Float
  • Example with Record Syntax:

    data Person = Person { name :: String, age :: Int }

18. Recursion

  • Functions can call themselves.
    sumList :: [Int] -> Int
    sumList []     = 0
    sumList (x:xs) = x + sumList xs

19. Input/Output (IO)

  • Haskell distinguishes pure functions from those that perform IO.
    main :: IO ()
    main = do
      putStrLn "Enter your name:"
      name <- getLine
      putStrLn ("Hello, " ++ name ++ "!")

20. Monads

  • Abstract data types used to represent computations.

  • Maybe Monad:

    safeDivide :: Double -> Double -> Maybe Double
    safeDivide _ 0 = Nothing
    safeDivide x y = Just (x / y)
  • Using do Notation with Monads:

    greet :: IO ()
    greet = do
      putStrLn "What is your name?"
      name <- getLine
      putStrLn ("Hello, " ++ name)

21. List Comprehensions

  • Generate lists based on existing lists.
    evenNumbers :: [Int]
    evenNumbers = [ x | x <- [1..20], even x ]

22. Modules and Imports

  • Defining a Module:

    module Geometry
      ( sphereVolume
      , sphereArea
      ) where
    
    sphereVolume :: Float -> Float
    sphereVolume r = (4.0 / 3.0) * pi * (r ^ 3)
  • Importing Modules:

    import Data.List
    import qualified Data.Map as Map

23. Lazy Evaluation

  • Expressions are evaluated only when needed.

  • Infinite Lists:

    ones = 1 : ones  -- Infinite list of 1s
  • Example with take:

    firstFiveOnes = take 5 ones  -- [1,1,1,1,1]

24. Error Handling

  • Using Maybe and Either for computations that may fail.
    findElement :: Eq a => a -> [a] -> Maybe Int
    findElement _ [] = Nothing
    findElement y (x:xs)
      | y == x    = Just 0
      | otherwise = fmap (+1) (findElement y xs)

25. Input and Output

  • Reading and Writing Files:
    main :: IO ()
    main = do
      contents <- readFile "input.txt"
      writeFile "output.txt" (process contents)
    
    process :: String -> String
    process = map toUpper

26. Common Prelude Functions

  • map: Applies a function to every element of a list.

    squares = map (^2) [1..5]  -- [1,4,9,16,25]
  • filter: Selects elements of a list that satisfy a predicate.

    evens = filter even [1..10]  -- [2,4,6,8,10]
  • foldl and foldr: Reduce a list to a single value.

    sumOfList = foldl (+) 0 [1..5]  -- 15

27. Handling Exceptions

  • Using Control.Exception:

    import Control.Exception
    
    main :: IO ()
    main = do
      result <- try (readFile "nonexistent.txt") :: IO (Either IOError String)
      case result of
        Left ex   -> putStrLn $ "An error occurred: " ++ show ex
        Right contents -> putStrLn contents

28. Using Packages with Cabal or Stack

  • Importing Third-Party Libraries:
    import Data.Text (Text)
    import qualified Data.Text as T
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant