JiwonDev

์•„์ฃผ ๋ฉ‹์ง„ ํ•˜์Šค์ผˆ์„ ๊ฐ™์ด ๋ฐฐ์›Œ๋ณด์ž #2

by JiwonDev

 

์ด ๊ธ€์—์„œ๋Š” ํ•˜์Šค์ผˆ ์„ค์น˜๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์–ธ๊ธ‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•˜๋‹ค๋ฉด ์•„๋ž˜ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ํ•˜์Šค์ผˆ ๊ฐœ๋ฐœ์— ํ•„์š”ํ•œ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•ด์ฃผ์„ธ์š”.

2021.03.11 - [๊ฐœ๋ฐœ ์–ธ์–ด/Haskell] - ํ•˜์Šค์ผˆ ๊ฐœ๋ฐœํ™˜๊ฒฝ (stack + IntelliJ plugin)

 

ํ•˜์Šค์ผˆ ๊ฐœ๋ฐœํ™˜๊ฒฝ (stack + IntelliJ plugin)

#1. ํ•˜์Šค์ผˆ ์ปดํŒŒ์ผ๋Ÿฌ ๊ฐ€์žฅ ๋งŽ์ด ์“ฐ์ด๋Š” ํ•˜์Šค์ผˆ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” GHC(glasgow haskell compiler)์ด๋ฉฐ ์ฝ˜์†”์ฐฝ์—์„œ ์‚ฌ์šฉ ์‹œ GHCI (GHC ์ธํ„ฐํ”„๋ฆฌํ„ฐ)๋ฅผ ์ด์šฉํ•ด์„œ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” Stack์„ ์ด์šฉํ•ด์„œ ์„ค์น˜

jiwondev.tistory.com

 

ํ•˜์Šค์ผˆ์€ ์ •๋ง ์—„๊ฒฉํ•œ ๋ฌธ๋ฒ•์„ ๊ฐ€์ง„ ์ˆœ์ˆ˜ ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋ผ์„œ Main์ฝ”๋“œ๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

๋ณดํ†ต stack ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์ด ๊ท€์ฐฎ๋‹ค๋ฉด ์•„๋ž˜ ์‚ฌ์ดํŠธ๋ฅผ ์ด์šฉํ•ฉ์‹œ๋‹ค.

Try Haskell! An interactive tutorial in your browser

 

#0. ํ•˜์Šค์ผˆ ์†Œ์Šค์ฝ”๋“œ

ํ•˜์Šค์ผˆ์ด ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜๋Š”์ง€ ๋Œ€์ถฉ ์‚ดํŽด๋ด…์‹œ๋‹ค. ๋ชจ๋ฅด๋Š” ๋ฌธ๋ฒ•์€ ์ฒœ์ฒœํžˆ ์•Œ์•„๊ฐ€๋ฉด ๋˜๋‹ˆ, ์ผ๋‹จ ๋„˜์–ด๊ฐ‘์‹œ๋‹ค.

-- Main.hs

-- Coord ๋ณ€์ˆ˜ ์ •์˜. ๋‹ค๋ฅธ ์–ธ์–ด์ฒ˜๋Ÿผ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ ์ •์˜๋งŒ ํ•œ๋‹ค.
type Coord = (Double, Double)

-- Config ๊ฐ์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ• (์ •ํ™•ํžˆ๋Š” ์ •์˜๋งŒ ํ•œ๋‹ค.)
data Config = Config { 
	rotAt :: Coord
	, theta :: Double
	, ofs :: (Double, Double)
}


-- ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜ ์ •์˜ ๋ฐฉ๋ฒ•. ๋ณ€์ˆ˜์˜ ์ •์˜์™€ ๋™์ผํ•˜๋‹ค.
type CoordConverter = Coord -> Coord


-- ์ด๋Ÿฐ์‹์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ์ง๊ด€์ ์œผ๋กœ ๋งŒ๋“ ๋‹ค.
-- trans ํ•จ์ˆ˜ ์ •์˜, dx์™€ dy๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ (x,y)์— ๋”ํ•œ๋‹ค.
trans :: (Double, Double) -> CoordConverter
trans (dx, dy) = \(x,y) -> (x+dx, y+dy)


-- rotate ํ•จ์ˆ˜ ์ •์˜, t๋ฅผ ์ž…๋ ฅ๋ฐ›์•„ (x,y)์— ๋”ํ•œ๋‹ค.
rotate :: Double -> CoordConverter
rotate t = \(x, y) -> ( x + t, y + t)


-- transByConfig ํ•จ์ˆ˜ ์ •์˜, config ๊ฐ์ฒด์˜ ์†์„ฑ ๊ฐ’์„ trans ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•œ๋‹ค.
-- config ๊ฐ์ฒด ์•ˆ์— ์žˆ๋Š” ofs๋ฅผ trans ํ•จ์ˆ˜์— ์ ์šฉํ•œ๋‹ค.
-- ofs :: (Double, Double)
transByConfig :: Config -> CoordConverter
transByConfig config = trans (ofs config)


-- rotateByConfig ํ•จ์ˆ˜ ์ •์˜, ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ config ๊ฐ์ฒด์˜ ์†์„ฑ๊ฐ’์„ rotate ํ•จ์ˆ˜์— ์ ์šฉ
-- theta :: Double
rotateByConfig :: Config -> CoordConverter
rotateByConfig config = postTrans . rotate (theta config) . preTrans where


-- ์œ„์—์„œ ๋งŒ๋“  ํ•จ์ˆ˜๋“ค์„ ์žฌ์‚ฌ์šฉํ•˜์—ฌ ๋” ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•œ๋‹ค.
rotateAt = rotAt config
preTrans = trans (rotate pi $ rotateAt)
postTrans = trans rotateAt

convertByConfig :: Config -> CoordConverter
convertByConfig config = transByConfig config . rotateByConfig config


-- ๋ฉ”์ธ์ฝ”๋“œ ์ •์˜
-- ์ฝ”๋“œ๊ฐ€ ํ•œ์ค„์ด ์•„๋‹ˆ๋ผ๋ฉด do ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ์ค„๋กœ ์ž‘์„ฑ ํ•  ์ˆ˜ ์žˆ๋‹ค.
-- ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ์ฝ˜์†” ์ž…๋ ฅ์„ ์ •์˜ํ•  ์ˆ˜ ์—†๋‹ค. ๊ทธ๋ž˜์„œ ๋ชจ๋‚˜๋“œ IO() ๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•œ๋‹ค.
main :: IO ()
main = do 
	let config = Config { rotAt = (0.5,0.5), theta = pi / 4, ofs = (-0.5, -0.5) }
	let unitRect = [(0,0),(0,1),(1,1),(1,0)]
	let convertedRect = map (convertByConfig config) unitRect

 

#1. ์ž๋ฃŒํ˜•

ํ•˜์Šค์ผˆ ๊ธฐ๋ณธ ํƒ€์ž…์€ Int, Integer, Double, Float, Bool, Char, String์ด ์žˆ๋‹ค.

์ž๋ฃŒํ˜•์€ ๊ธฐ๋ณธ์ ์œผ๋กœ let ์œผ๋กœ ์„ ์–ธํ•˜๋‚˜, ๋ณดํ†ต ์ƒ๋žตํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

  • Int๋Š” ์ตœ์†Œ -2^29๋ถ€ํ„ฐ +2^29์˜ ๋ฒ”์œ„๋ฅผ ๋ณด์žฅํ•˜๋Š” ์ •์ˆ˜์ž…๋‹ˆ๋‹ค. (* OS์— ๋”ฐ๋ผ ๋ฒ”์œ„๊ฐ€ ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์žˆ๋‹ค.)
  • Integer๋Š” ๊ฐ’์˜ ํ•œ๊ณ„๊ฐ€ ์—†๋Š” ์ •์ˆ˜ ํƒ€์ž…์ด๋‹ค.
  • Double๊ณผ Float๋Š” ๊ฐ๊ฐ ๋ฐฐ์ •๋ฐ€๋„, ๋‹จ์ •๋ฐ€๋„ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆ˜ ํƒ€์ž…์ด๋‹ค.
  • Bool์€ True์™€ False๋ฅผ ์œ ์ดํ•œ ๊ฐ’์œผ๋กœ ๊ฐ€์ง€๋Š” ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์ด๋‹ค.
  • Char๋Š” ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž๋ฅผ ํ‘œํ˜„ํ•˜๋Š” ํƒ€์ž…์ด๋‹ค.
  • String์€ Char์˜ ๋ฆฌ์ŠคํŠธ์ง€๋งŒ, ๋ฌธ์ž์—ด ํ‘œํ˜„์„ ํ—ˆ์šฉํ•œ ํƒ€์ž…์ด๋‹ค.
let lostNumbers = [4,8,15,16,23,42]
-- let์„ ์ƒ๋žตํ•ด๋„ ์ƒ๊ด€์—†๋‹ค.
-- lostNumbers = [4,8,15,16,23,42]

"HELLO" 
-- ํ•˜์Šค์ผˆ์—์„œ ์ŠคํŠธ๋ง์€ ๋ฌธ์ž์—ด์„ ํ—ˆ์šฉํ•œ ๋ฆฌ์ŠคํŠธ ์ž๋ฃŒํ˜•์ด๋‹ค.
-- ['H','E','L','L','O']
-- types.hs
i :: Int
i = -78
 
biggestInt, smallestInt :: Int
biggestInt  = maxBound -- ์ž๋ฃŒํ˜•์˜ ์ตœ๋Œ€๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
smallestInt = minBound -- ์ž๋ฃŒํ˜•์˜ ์ตœ์†Œ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
 
-- ์ž„์˜ ํฌ๊ธฐ ์ •์ˆ˜
n :: Integer
n = 1234567890987654321987340982334987349872349874534

19 - 27
(-3) * (-7) -- ์Œ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
 
-- ๋ฐฐ์ •๋ฐ€๋„ ๋ถ€๋™์†Œ์ˆ˜์  ์ˆ˜
d1, d2 :: Double
d1 = 4.5387
d2 = 6.2831e-4
 
-- ๋ถˆ๋ฆฌ์–ธ
b1, b2, b3 :: Bool
b1 = True
b2 = False
b3 = not (False || b1) && ( b2 || True)
 
-- ์œ ๋‹ˆ์ฝ”๋“œ ๋ฌธ์ž
c1, c2, c3 :: Char
c1 = 'x'
c2 = 'Ø'
c3 = 'ใƒ€'
 
-- ๋ฌธ์ž์—ด
s :: String
s = "Hello, Haskell!"

 

์ฐธ๊ณ ๋กœ ํ•˜์Šค์ผˆ์€ ์ž๋ฃŒํ˜•์— ๋งค์šฐ ์—„๊ฒฉํ•œ ๊ทœ์น™์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

True == 1 
-- ์ปดํŒŒ์ผ ์—๋Ÿฌ!

5 + 4.0 
-- ์ด๋Š” 5(INT)๊ฐ€ 5.0(DOUBLE)์œผ๋กœ ๋ณ€ํ™˜๋˜์–ด ์ธ์‹ํ•˜๊ฒŒ ๋œ๋‹ค.
-- ๋‹จ ๋ฐ˜๋Œ€๋กœ doubleํ˜•์ด int๋กœ ์บ์ŠคํŒ… ๋˜๋Š” ๊ฒฝ์šฐ๋Š” ์—†๋‹ค. ํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ!

 


 

#2. ํ•จ์ˆ˜

ํ•˜์Šค์ผˆ์—์„œ๋Š” ํ•จ์ˆ˜๋„ ๋ณ€์ˆ˜์™€ ๋™์ผํ•˜๊ฒŒ ์ •์˜(์„ ์–ธ)ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ, ํ•จ์ˆ˜ ์ด๋ฆ„๊ณผ ํŒŒ๋ผ๋ฉ”ํƒ€ ๋ณ€์ˆ˜ ์‚ฌ์ด ๊ณต๋ฐฑ๋งŒ์œผ๋กœ ๊ตฌ๋ถ„ ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ๊ด„ํ˜ธ๋ฅผ ์ƒ๋žตํ•ด๋„ ์ƒ๊ด€์—†๋‹ค.

 

  • ์ด๋ฆ„ :: ์„ ์–ธ ๋ณ€์ˆ˜์™€ ๋˜‘๊ฐ™์ด :: ๊ธฐํ˜ธ๋ฅผ ์‚ฌ์šฉํ•ด ์ •์˜ํ•œ๋‹ค.

-> ๋Š” ์™ผ์ชฝ ํƒ€์ž…์˜ ๊ฐ’์„ ์ธ์ž(์ž…๋ ฅ, ๋งค๊ฐœ๋ณ€์ˆ˜)๋กœ ๋ฐ›์•„์„œ ์˜ค๋ฅธ์ชฝ์— ์ „๋‹ฌํ•˜๋Š” ํ•จ์ˆ˜๋ผ๋Š” ์˜๋ฏธ์ด๋‹ค.

parity :: Integer -> Integer
parity n = if (n `mod` 2) == 0 then 0 else 1 
-- parity n = n `mod` 2 ๋กœ๋„ ๊ฐ€๋Šฅ
 
{- ์ฐธ๊ณ ๋กœ mod๊ฐ™์€ ํ•จ์ˆ˜๊ฐ€ ๊ฐ’ ๊ฐ€์šด๋ฐ ๋“ค์–ด๊ฐˆ ๋•Œ๋Š” ' ' ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. -}
mod 19 3
19 'mod' 3

 

  • ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฌ๊ท€์ ์ธ ํ˜ธ์ถœ๋„ ์ž์ฃผ ์‚ฌ์šฉ๋œ๋‹ค.
-- sumtorial.hs
-- 1๋ถ€ํ„ฐ n๊นŒ์ง€ ์ •์ˆ˜์˜ ํ•ฉ์„ ๊ณ„์‚ฐํ•œ๋‹ค
sumtorial :: Integer -> Integer
sumtorial 0 = 0
sumtorial n = n + sumtorial (n-1)

 

  • ์ธ์ž๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋ฉด ์ปค๋ง(currying)์„ ์ด์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ ํ•  ์ˆ˜ ์žˆ๋‹ค.
-- args.hs
f :: Int -> Int -> Int -> Int
f x y z = x + y + z
 
ex17 = f 3 17 8  -- 28

 

  • ๋ฌผ๋ก , ๊ธฐ์กด์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ธ์ž๋ฅผ ํŠœํ”Œ(Pair)๋กœ ๋ฌถ์–ด์„œ ํ•˜๋‚˜์ฒ˜๋Ÿผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ๋„ ์žˆ๋‹ค.
p :: (Int, Char)
p = (3, 'x')
 
-- sumPair.hs
sumPair :: (Int,Int) -> Int
sumPair (x,y) = x + y

 

#3. ํ•จ์ˆ˜์˜ ์ปค๋ง (Curring)

์ธ์ž๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ๋ฐ›๋Š” ํ•จ์ˆ˜๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ, ์ธ์ž๋ฅผ ํ•˜๋‚˜์”ฉ๋งŒ ๋ฐ›๋„๋ก ๋งŒ๋“œ๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.

๊ตฌํ˜„์€ ์กฐ๊ธˆ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์ง€๋งŒ, ํ•จ์ˆ˜์˜ ์žฌ์‚ฌ์šฉ์„ฑ๊ณผ ๊ฐ€๋…์„ฑ์„ ์˜ฌ๋ ค์ค€๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

 

ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ๋ฐ˜ํ™˜ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ˜ํ™˜ ๊ฐ’์— ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์˜ˆ๋ฅผ ๋“ค์–ด๋ณด์ž

// uncurrying
function greet(greeting, name){
    console.log(greeting + , ", " + name);
}

greeting("Hello","Jiwon");
// currying
function greet(greeting){
    return function(name){
        console.log(greeting + ", " + name);
    }
}

greet('Hello')('Jiwon')

 

ํ•จ์ˆ˜์˜ ๊ตฌํ˜„์€ ๊นŒ๋‹ค๋กญ๊ฒŒ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์ปค๋ง์„ ์ด์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฒด์ด๋‹(Chaining) ๋ฌธ๋ฒ•์„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค

function multiplyThree(x) {
  return function(y) {
    return function(z) {
      return x * y * z;
     }
  };
}
multiplyThree(4)(8)(2); 
// multiplyThree(x) ์˜ ๋ฐ˜ํ™˜๊ฐ’์€ function์ด๋ผ ์ด๋Ÿฐ์‹์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด ๊ฐœ๋ฐœ์ž๋“ค๋„ ์ด๋ ‡๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์–ด๋ ต๊ณ  ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง„๋‹ค๋Š” ๊ฑธ ์•Œ๊ณ  ์žˆ๊ธฐ์—, ๋ณดํ†ต ํ•˜์Šค์ผˆ ์ฒ˜๋Ÿผ ํ•œ ์ค„๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜ํ˜• ๋ฌธ๋ฒ•(ํ™”์‚ดํ‘œ ํ•จ์ˆ˜, ๋žŒ๋‹ค ๋“ฑ)์„ ๋”ฐ๋กœ ์ œ๊ณตํ•ด์ค€๋‹ค.

// ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜, ์œ„์˜ greet()๊ณผ ๋™์ผํ•œ ํ•จ์ˆ˜์ด๋‹ค.
greet = greeting => name => console.log(greeting + ', ' + name);
//    = gretting => function() {...}
//    = gretting => ( name => console.log )
greet('Hello')('name')

mulriplyThree = x => y => z => x * y * z;
multiplyThree(4)(8)(2); 

 

#4. ์กฐ๊ฑด๋ฌธ (if, guard)

  • ํ•˜์Šค์ผˆ์—์„œ if๋ฌธ์„ ์ง€์›ํ•˜๊ธด ํ•˜์ง€๋งŒ, ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์—์„œ๋Š” ์ž˜ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.
-- b๊ฐ€ ์ฐธ์ด๋ฉด t๋ฅผ, ๊ฑฐ์ง“์ด๋ฉด f๋ฅผ ๊ฐ’์œผ๋กœ ๋Œ€์ž…ํ•œ๋‹ค.(์ •์˜ํ•œ๋‹ค)
if b then t else f

 

ํ•จ์ˆ˜ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” ์กฐ๊ฑด ์ ˆ์€ {key : value} ๊ฐ™์€ ์ž๋ฃŒํ˜•์„ ์ด์šฉํ•ด ํŒจํ„ด ๋งค์นญ์„ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

ํ•˜์Šค์ผˆ์—์„  guard( | ) ์—ฐ์‚ฐ์ž๋ฅผ ์ ์ ˆํžˆ ์ด์šฉํ•ด์„œ ํŒจํ„ด ๋งค์นญ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค..

parity2 :: Integer -> Integer
parity2 n
  | n `mod` 2 == 0 = 100 // n%2 == 0 ์ด๋ฉด 100 ๋ฐ˜ํ™˜
  | otherwise == 1 = 200 // else 200 ๋ฐ˜ํ™˜
  
  // else == otherwise
count :: Integer -> String
count 0 = "ํŒจํ„ด๋งค์นญ0" 
count 1 = "ํŒจํ„ด๋งค์นญ1"
count 2 = "ํŒจํ„ด๋งค์นญ2" 
count n = "Default"

๋ณดํ†ต ์•„๋ž˜์™€ ๊ฐ™์ด ์œ„์˜ 2๊ฐ€์ง€ ๋ฌธ๋ฒ•์„ ์ ์ ˆํžˆ ์„ž์–ด ์‚ฌ์šฉํ•œ๋‹ค.

-- foo.hs
foo :: Integer -> Integer
foo 0 = 16
foo 1 
  | "Haskell" > "C++" = 3
  | otherwise         = 4
foo n
  | n < 0            = 0
  | n `mod` 17 == 2  = -43
  | otherwise        = n + 3

 

#5. Type๊ณผ Data

Type

์„ ์–ธํ•˜์ง€ ์•Š์•„๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ํƒ€์ž…๋„ ์žˆ์ง€๋งŒ, ์šฐ๋ฆฌ๊ฐ€ ์ง์ ‘ ํƒ€์ž…์„ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด๋„ ๋œ๋‹ค.

-- ์ŠคํŠธ๋ง์€ [Char] ํƒ€์ž…์ด๋‹ค.
type MyString = [Char] 
type Pos = (Int, Int)

str :: MyString
str = "Hello"

origin :: Pos
origin = (0, 0)

left :: Pos -> Pos
left (x, y) = (x-1, y)

 

  • ์ฐธ๊ณ ๋กœ ๊ฐ์ฒด์˜ ํƒ€์ž…์„ ์•Œ๊ณ ์‹ถ๋‹ค๋ฉด :type ๋˜๋Š” :t ๋ฅผ ์ด์šฉํ•˜๋ฉด ํƒ€์ž…์„ ์ถœ๋ ฅ ํ•  ์ˆ˜ ์žˆ๋‹ค.
Prelude> :type True
True :: Bool

Prelude> :t (3 < 5)
(3 < 5) :: Bool

Prelude> :t 'H'   -- ๋”ฐ์Œํ‘œ๋Š” ํ•œ ๋ฌธ์ž (Char)์„ ์˜๋ฏธํ•œ๋‹ค.
'H' :: Char

Prelude> :t "Hello World"   -- ์Œ ๋”ฐ์Œํ‘œ๋Š” ์ŠคํŠธ๋ง(=๋ฆฌ์ŠคํŠธ)์„ ์˜๋ฏธํ•œ๋‹ค
"Hello World" :: [Char]

 

Data

๋‹ค๋ฅธ ์–ธ์–ด์˜ MyClass a = MyClass() ์ฒ˜๋Ÿผ ์•„์˜ˆ ์ƒˆ๋กœ์šด ์ž๋ฃŒํ˜•์„ ๋งŒ๋“ค๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ Data ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

-- Bool ์ž๋ฃŒํ˜•์€ False์™€ True๋ฅผ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
data Bool = False | True
-- Answer ์ž๋ฃŒํ˜•์€ Yes์™€ No์™€ Unknown์„ ๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
data Answer = Yes | No | Unknown

answers :: [Answer]
answers = [Yes, No, Unknown]

flip :: Answer -> Answer
flip Yes = No
flip No = Yes
flip Unknown = Unknown
data Move = Left 
	| Right 
	| Up 
	| Down

move :: Move -> Pos -> Pos
move Up (x, y) = (x, y-1)
move Left (x, y) = (x-1, y)
move Down (x, y) = (x, y+1)
move Right (x, y) = (x+1, y)

moves :: [Move] -> Pos -> Pos
moves [] p = p
moves (m:ms) p = moves ms (move m p)

> move Left (1, 1)
-- ์ถœ๋ ฅ๊ฐ’: (0,1)

> moves [Left, Right, Up, Down, Left] (0, 0)
-- ์ถœ๋ ฅ๊ฐ’: (-1,0)

#6. list (๋ฆฌ์ŠคํŠธ)์˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ™์€ ์ž๋ฃŒํ˜•์„ ๊ฐ€์ง„ ๊ฐ’๋“ค์„ ํ•˜๋‚˜๋กœ ํ•ฉ์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ( ์ž๋ฃŒํ˜•์ด ๋‹ค๋ฅด๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ )

-- let์€ ์ƒ๋žตํ•ด๋„ ์ƒ๊ด€์—†๋‹ค.
let numbers = [1,2,3,4]
let truths  = [True, False, False]
let strings = ["here", "are", "some", "strings"]


-- ์•ž์—๋„ ๋งํ–ˆ์ง€๋งŒ, ํ•˜์Šค์ผˆ์˜ ๋ฌธ์ž์—ด์€ ๋ฆฌ์ŠคํŠธ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๋‹ค.
"hello"
// ['h','e','l','l','o']


-- ๋ฆฌ์ŠคํŠธ ์ค‘์ฒฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
-- ์•„๋ž˜์˜ ๊ฒฝ์šฐ ์ž๋ฃŒํ˜•์€ [Int]์ด๋‹ค. ์ด๋Š” Int์™€ ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์œผ๋กœ ํŒ๋‹จํ•œ๋‹ค.
let listOfLists = [[1,2],[3,4],[5,6]]

 

  • ๋ฆฌ์ŠคํŠธ์™€ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์„ ์ด์–ด ๋ถ™์ด๊ณ  ์‹ถ๋‹ค๋ฉด ๊ฐ’์„ ๊ฑด๋„ค์ฃผ๋Š” Constructor ์—ฐ์‚ฐ์ž (:)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
5:[1,2,3,4]
-- ์ถœ๋ ฅ๊ฐ’ : [5,1,2,3,4]

'๊ฐ€' : "๋‚˜๋‹ค๋ผ๋งˆ"
-- ์ถœ๋ ฅ๊ฐ’ : "๊ฐ€๋‚˜๋‹ค๋ผ๋งˆ"

1:2:3:[]
-- ์ถœ๋ ฅ๊ฐ’ : [1,2,3]

 

  • ๋ฆฌ์ŠคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” Concate ์—ฐ์‚ฐ์ž(++)๋ฅผ ์ด์šฉํ•ด ๋‘ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ด์–ด ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค.
[1,2,3,4] ++ [9,10,11,12]
-- ์ถœ๋ ฅ๊ฐ’ : [1,2,3,4,9,10,11,12]  

'WO' ++ 'OT'
--  ์ถœ๋ ฅ๊ฐ’ : 'WOOT'

['w','o'] ++ ['o','t'] 
--  ์ถœ๋ ฅ๊ฐ’ : 'woot'

 

  • ๋ฆฌ์ŠคํŠธ์˜ ํŠน์ • ์ธ๋ฑ์Šค ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด (!! n)์„ ์‚ฌ์šฉํ•œ๋‹ค.
 "Steve Buscemi" !! 6
 -- ์ถœ๋ ฅ๊ฐ’ 'B' (6๋ฒˆ์งธ ์ธ๋ฑ์Šค ๊ฐ’)
 
 [0, 1, 2, 3, 4] !! 1  
 -- ์ถœ๋ ฅ๊ฐ’ 1

 

  • ์ด์ค‘์  ์—ฐ์‚ฐ์ž(..)๋ฅผ ์ด์šฉํ•ด ์—ฐ์†์ ์ธ ๊ฐ’์ด๋‚˜ ๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[1..10]          --์ถœ๋ ฅ๊ฐ’ : [1,2,3,4,5,6,7,8,9,10]
[2,4..10]        --์ถœ๋ ฅ๊ฐ’ : [2,4,6,8,10]
[5,4..1]         --์ถœ๋ ฅ๊ฐ’ : [5,4,3,2,1]
[1,3..10]        --์ถœ๋ ฅ๊ฐ’ : [1,3,5,7,9]


[1..] -- ๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ

-- ๋‹น์—ฐํžˆ ๋ฌดํ•œ๋ฆฌ์ŠคํŠธ ์ž์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋Š” ์•Š๊ณ , ์ผ๋ถ€๋ฅผ ์ถ”์ถœํ•ฉ๋‹ˆ๋‹ค.
-- take ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฌดํ•œ๋ฆฌ์ŠคํŠธ์˜ ์ผ๋ถ€๋ถ„ ์ถ”์ถœ
take 10 [1..]   -- ์ถœ๋ ฅ๊ฐ’: [1,2,3,4,5,6,7,8,9,10]

 

  • ๋ฆฌ์ŠคํŠธ๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ์ƒ์„ฑ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋งŒ์•ฝ ๋งˆ์ง€๋ง‰ ๊ฐ’(๋นˆ ๋ฆฌ์ŠคํŠธ)์˜ ์ฒ˜๋ฆฌ๋ฅผ ์ ์ง€์•Š์œผ๋ฉด ์žฌ๊ท€ํ•จ์ˆ˜๊ฐ€ ๋๋‚˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฌดํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค.
doubleList :: [Integer] -> [Integer]
doubleList [] = []   -- ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ž…๋ ฅ๋ฐ›์œผ๋ฉด ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
doubleList (n:ns) = (n * 2) : doubleList ns   -- ๊ทธ ์™ธ ์ž…๋ ฅ
doubleList [1,2,3,4]
-- ์ถœ๋ ฅ๊ฐ’ : [2,4,6,8]

{- ์ด ์ฝ”๋“œ๋Š” ์•„๋ž˜์˜ ์ •์˜์™€ ๋˜‘๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.  -}
doubleList 1:[2,3,4] = (1*2) : doubleList (2 : [3,4])
                     = (1*2) : (2*2) : doubleList (3 : [4])
                     = (1*2) : (2*2) : (3*2) : doubleList (4 : [])
                     = (1*2) : (2*2) : (3*2) : (4*2) : doubleList []
                     = (1*2) : (2*2) : (3*2) : (4*2) : []
                     = 2 : 4 : 6 : 8 : []
                     = [2, 4, 6, 8]

 

์šฐ์™€! ์˜ค๋Š˜์น˜ ๊ณต๋ถ€ ๋‹คํ–ˆ๋‹ค!

ํ•˜์Šค์ผˆ์€ ๋Ÿฌ๋‹์ปค๋ธŒ(๋ฐฐ์šฐ๋Š” ๊ณผ์ •)์ด ๋”์ฐํ•œ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ๊นŒ์ง€ ์ฝ๋Š”๋‹ค๊ณ  ๊ณ ์ƒํ•˜์…จ์Šต๋‹ˆ๋‹ค.

์•„์ง ์„ค๋ช…์•ˆํ•œ ๋‚ด์šฉ์ด ๋งŽ์ง€๋งŒ, ์ผ๋‹จ ํ•œ๋ฒˆ ์‰ฌ์–ด๊ฐ€๋„๋ก ํ•ฉ์‹œ๋‹ค.

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ