-
[Haskell] #6 syntax-in-functions (1)๊ณต๋ถ/ํจ์ํ ํ๋ก๊ทธ๋๋ฐ 2020. 1. 27. 21:43
์๋ ํ์ธ์. Lemon Kim ์ ๋๋ค ๐
์ค๋์ ๋๋์ด!! ํจ์์์ pattern matching, guard์ where, let, case๋ฌธ์ ํตํด์ ๋ฐ๋ณต์ ํ๊ฑฐ๋, if-else๋ฌธ์ ๋์นํด์ ํจ์๋ฅผ ์งง๊ฒ ๋ง๋๋ ๋ฒ์ ๋ฐฐ์ธ ์ ์์์ด์. ์ด ๋ค์ ์ฅ์ธ ์ฌ๊ท๋ฅผ ๋ฐฐ์ฐ๊ณ ๋๋ฉด, ๊ทธ๋๋ HackerRank์ ๊ธฐ๋ณธ์ ์ธ ๋ฌธ์ ๋ค์ ํธ๋ ๊ฒ์ด ๊ฐ๋ฅํด ์ง ๊ฑฐ์์.
์ด์ ํธ
2020/01/20 - [๊ณต๋ถ/ํจ์ํ ํ๋ก๊ทธ๋๋ฐ] - [Haskell] #5 Type (2)
์์ด ์๋ฌธ์ ์ฌ๊ธฐ http://learnyouahaskell.com/syntax-in-functions
๋ชฉ์ฐจ
1. pattern matching
- Non-Exaustive์ ์์
- Factorial ๊ตฌํ์ผ๋ก ์์๋ณด๋ ์ฌ๊ท
- ๋ฆฌ์คํธ, ํํ๊ณผ ํจํด ๋งค์นญ
2. guard, where
3. let
4. case
์ค๋ ๋ค๋ฃฐ ๋ด์ฉ์ 1๋ฒ pattern matching ์ด์์! (์ ๋๋์๋ ํ๋ฉด... ์ค๋๋ ์ ๋ฆฌํ ๋ด์ฉ์ด ๋๋ฌด ๋ง์์ ธ์...)
1. pattern matching
ํจํด ๋งค์นญ์ ์ฌ์ฉํด์, ํน์ ํ ์ํฉ์ ๋ฏธ๋ฆฌ ์ ์ํด์ ๋จผ์ ์์ ์ ์ด๋๊ณ , ๋๋จธ์ง๋ x ๋ฑ์ ๋ณ์๋ฅผ ์ด์ฉํด์ ํจ์๋ฅผ ์ ์ํด์ค ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด์, ์ฑ ์์ ๋์จ ์์ ์ฒ๋ผ ์ ๋ ฅ์ด 7์ผ ๋๋ "lucky seven"์, ๋๋จธ์ง๋ "Oh, you're out of luck" ์ ์ถ๋ ฅํ๋ ๊ฒ์ฒ๋ผ ๊ฐ๋จํ ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค.
lucky :: (Integral a) => a -> String //ํจ์ ์ ์ธ
lucky 7 = "LUCKY NUMBER SEVEN!"
//์ฌ๊ธฐ๋ถํฐ ํจ์ body ์ ๋๋ค. 7์ ๋ํ ํน์ ์ํฉ์ ๋ณด์ฌ์ฃผ๋ค์!
lucky x = "Sorry, you're out of luck, pal!"
// ๋๋จธ์ง๋ ๋ณ์ x๊ฐ ๋ด๋นํฉ๋๋ค.1. Non-Exaustive์ ์์
๋ฒ์๊ฐ ์กด์ฌํ๋ Char ๋ฑ์ ๊ฒฝ์ฐ์, ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๋์ํด ์ฃผ์ง ์์ ๊ฒฝ์ฐ, ๋์ํ์ง ์์ ์ผ์ด์ค์ ์ ๋ ฅ์ด ๋ค์ด์ค๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
์๋ ์๋ฅผ ๋ณด์ฃ !
sayHi :: Char -> String
sayHi 'a' = "Hello, " ++ "Ain"
sayHi 'b' = "Hello, " ++ "Benjamin"
sayHi 'c' = "Hello, " ++ "Carmen"
sayHi 'a'
=>Hello, Ain
sayHi 'l' //์๋ ์ผ์ด์ค์ฃ ?
*** Exception: main.hs:(7,1)-(9,33): Non-exhaustive patterns in function sayHiexhaustive๋ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํ๋ค๊ณ ํด์. (๋งํฌ๋ ๋ฏธ๋ฆฌ์ ์น์คํฐ ์ฌ์ ์ ์๋ก)
์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด, ์๋ ์ฝ๋์ x ๋ฑ์ ๋ณ์๋ฅผ ๋ฃ์ด์ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํด์ฃผ๋ฉด ๋๊ฒ ์ฃ ?
sayHi :: Char -> String
sayHi 'a' = "Hello, " ++ "Ain"
sayHi 'b' = "Hello, " ++ "Benjamin"
sayHi 'c' = "Hello, " ++ "Carmen"
sayHi x = "Hello, strange. what's your name?" //๋ชจ๋ ๊ฒฝ์ฐ์ ๋ํด์ ์ถ๊ฐํด ์ฃผ์์ด์!
sayHi 'a'
=> Hello, Ain
sayHi 'l' //์๋ ์ผ์ด์ค์ฃ ?
=> Hello, strange. what's your name? //์ด์ ์ ๋์ค๋ค์๊ทธ๋ฆฌ๊ณ ๋ ๋ฒ์งธ๋ก, ํจํด ๋งค์นญ์ ์์์ ๋ถํฐ ์์๋๋ก ์ผ์ด๋ฉ๋๋ค. ์์๊ฐ ์ค์ํด์.
sayHi :: (Integral a) => a -> String
sayHi x = "hi, stranger!"
sayHi 1 = "hi, 1"
sayHi 1
=> hi, stranger!์๋๋ "hi, 1"์ด ๋์์ผ ํ๊ฒ ์ง๋ง, "hi, stranger"๊ฐ ๋์ ์ถ๋ ฅ๋ฉ๋๋ค.
ํจํด๋งค์นญ์ด ์์๋๋ก ์ผ์ด๋์ ์๊ธฐ๋ ํ์์ ๋๋ค.
์์ฒ๋ผ x๊ฐ ๋ชจ๋ ๊ฒ์ ๋์ ํ ์ ์๋ ๊ฒฝ์ฐ, ์คํ์ ๋์ง๋ง ์๋ ๊ฐ์ warning์ ์ถ๋ ฅํ๋ค์.
main.hs:3:1: warning: [-Woverlapping-patterns] Pattern match is redundant In an equation for ‘sayHi’: sayHi 1 = ... | 3 | sayHi 1 = "hi, 1" | ^^^^^^^^^^^^^^^^^2. Factorial ๊ตฌํ์ผ๋ก ์์๋ณด๋ ์ฌ๊ท
ํจํด ๋งค์นญ์ผ๋ก ์ฌ๊ท๋ฅผ ๊ตฌํ ํ ์ ์์ต๋๋ค.
Factorial์ ์ ์๋ฅผ ์ ์ ์๊ฐํด๋ณผ๊น์?
factorial (0) = 1
factorial (n) = n * factorial(n - 1)์์ ๋ฌธ์๋ฅผ ํจํด ๋งค์นญ์ผ๋ก ๊ทธ๋๋ก ์ฎ๊ธธ ์ ์์ต๋๋ค.
myFactorial :: (Integral a) => a -> a
myFactorial 0 = 1
myFactorial n = n * myFactorial (n-1) //์ด๋ฅผ ํตํด์ factorial์ n ๋ฒ ๋ฐ๋ณตํ ์ ์์ต๋๋ค.
myFactorial 3 => 6
myFactorial 0 => 1์ด๋ฅผ ์์ฉํด, ๋ฐ๋ณต๋ฌธ์ ๊ตฌํํ ์ ์๊ฒ ๋น์.
3. ๋ฆฌ์คํธ, ํํ๊ณผ ํจํด ๋งค์นญ
๋น์ฐํ ๊ธฐ๋ณธ ํ์ ์ธ ํํ, ๋ฆฌ์คํธ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์์ ๋ ์์ ๋งํฌ์ ๊ต์ฌ์์ ๊ฐ๊ณ ์์ต๋๋ค.
ํํ์์ ์ฌ์ฉํ๊ธฐ
addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)
addVectors a b = (fst a + fst b, snd a + snd b)
//์์ ํจ์๋ฅผ ์๋์ฒ๋ผ ํจํด ๋งค์นญ์ ์ฌ์ฉํด ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
addVectors :: (Num a) => (a, a) -> (a, a) -> (a, a)
addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)๋ฆฌ์คํธ์์ ์ฌ์ฉํ๊ธฐ
head' :: [a] -> a
head' [] = error "Can't call head on an empty list, dummy!" //๋น ๋ฆฌ์คํธ์ ๊ฒฝ์ฐ๋ฅผ ํจํด ๋งค์นญ์ ํ์ฉํด ์ฒ๋ฆฌํ๊ณ ์์ต๋๋ค.
head' (x:_) = x //๋น ๋ฆฌ์คํธ๊ฐ ์๋ ๋๋จธ์ง ๊ฒฝ์ฐ.๋ฆฌ์คํธ์์ ํจํด ๋งค์นญ์ ์ฌ์ฉํ ๋, : ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํด์, x:y:z:[] ๋ฑ์ ํํ๋ก, ๋ค์ด์ค๋ ๋ฆฌ์คํธ์ ๊ฐฏ์๋ฅผ ํจํด ๋งค์นญ์ผ๋ก ์ ํํ๊ฑฐ๋ ํ์ฉํ ์ ์์ต๋๋ค.
์ฑ ์์๋ ์ด ํ์ฉ์ ํนํ ์ฌ๊ท ํจ์๋ฅผ ๊ตฌํ ํ ๋, ๋ง์ด ์ฌ์ฉํ๋ค๊ณ ํ๋๋ฐ์, ์๋ง ๋ค์ ์ฅ์ ๋์ค์ง ์์๊น ์ถ๋ค์!
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:y: []) = "The list has two elements: " ++ show x ++ " and " ++ show y
tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y์ค๋์ ์ฌ๊ธฐ๊น์ง์์! ๋ค์ ์๊ฐ์๋ guard์ where๋ฅผ ์ฌ์ฉํ๋ ๋ฒ์ ์ ๋ฆฌํด๋ณด๋๋ก ํ ๊ฒ์.
์ค๋ ๊ณ ์ ๋ง์ผ์ จ์ด์. ์ข์ ํ๋ฃจ ๋์๊ธธ ๋ฐ๋๋๋ค :)
+ ๋ณด๋์ค : ํ์ผ์ ์ง์ ์ปดํ์ผํด์ main ํจ์์์ ์ถ๋ ฅ ํ ๋ ์ฃผ์ํ ์ . putStrLn์ ์ฐ๋ฉด show ๋ฑ์ผ๋ก ๋ฌธ์์ด๋ก ๋ฐ๊พธ์ด์ฃผ์.
๊ณต๋ถ๋ ํ ๊ฒธ main ํ์ผ๋ก ๋ง๋ค์ด์ ์ปดํ์ผ ํ๋๊น ๊ณ์ ์๋์... ์์ฒญ ๋ต๋ตํด ํ๋ค ํด๊ฒฐํด์ ๋จ๊น๋๋ค.
๋ฌธ์ ๊ฐ ๋ main ํ์ผ
myFactorial :: (Integral a) => a -> a
myFactorial 0 = 1
myFactorial n = n * myFactorial (n-1)
main = do
putStrLn (myFactorial 3)์๋ฌ ๋ฉ์์ง
main.hs:27:13: error: • No instance for (Integral String) arising from a use of ‘myFactorial’ • In the first argument of ‘putStrLn’, namely ‘(myFactorial 3)’
๊ณ์ ์ด๋ ๊ฒ ์ ๋๊ธธ๋... ๋๋์ฒด ๋ญ๊ฐ ๋ฌธ์ ์ง?!? ํ๋ค๊ฐ ๋๋จธ์ง ์์ ์ putStrLn์ ๋ชจ๋ String์ ์ธ์๋ก ๋ฐ๊ณ ์์ผ๋... ์ค๋ง...ํ๊ณ
show ํจ์๋ฅผ ์ฌ์ฉํ๋๋... ํด๊ฒฐ...
ํด๊ฒฐํ main ํ์ผ
//์์ ๋ด์ฉ์ ๊ฐ์์... just show๋ง ์ถ๊ฐ...
putStrLn (show(myFactorial 3))ํน์๋ผ๋ main์์ ์ถ๋ ฅํด์ผํ๋ ์๊ณ ๋ฆฌ์ฆ ๋ฌธ์ ๋ฅผ ํ๊ณ ๊ณ์๊ฑฐ๋ main ๋ฌธ์ ์ฌ์ฉํ์๋ ๋ถ๋ค์ ์ฐธ๊ณ ํด์ฃผ์ธ์...ใ ใ ...
'๊ณต๋ถ > ํจ์ํ ํ๋ก๊ทธ๋๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Haskell] 5 - 3. $ (function application) (0) 2020.02.16 [Haskell] #5 Type (2) (0) 2020.01.20 [Haskell] #4 Type (1) (0) 2020.01.19 [Haskell] #3 Tuple (0) 2020.01.12 [Haskell] #2 List(2) Range, list comprehension (0) 2020.01.12