灰暗已經(jīng)過去旁涤,又開始寫文章啦啦啦5枞础!柳骄!
1熊泵, 之前學習大數(shù)據(jù)要用到scala語言仰迁,遇到scala里面的函數(shù)式部分有點懵逼。后來就想深入學習一下函數(shù)式語言⊥绶郑現(xiàn)在的很多命令式語言都支持函數(shù)式風格徐许,但是因為命令式的思想根深蒂固多年很多函數(shù)式的思想很難理解。于是就想直接從一門純粹的函數(shù)式語言入手從零開始學習函數(shù)式編程思想卒蘸。去年在工作空閑時花過一段時間學習haskell雌隅,當時有點暈,很多東西沒搞明白,后來事情太多中斷了恰起。如今有空了修械,再繼續(xù)吧。
本文先從Haskell Cookbook上的求解一元二次方程開始吧检盼,熟悉一下語法祠肥。
2, 配置環(huán)境:按照haskell文檔安裝stack梯皿,別用brew install stack,版本太舊县恕,問題多多东羹。
haskell官方IDE是基于eclipse的,不太好用忠烛,目前直接使用vs code属提。
3, stack new hello新建工程美尸。
項目結(jié)構(gòu).png
-- Quadratic.hs
module Quadratic where
-- 導(dǎo)入模塊
import Data.Complex
-- 定義數(shù)據(jù)類型:record格式
-- =號左邊叫類型構(gòu)造冤议,可以接受類型參數(shù),相當于定義泛形類型
-- =號右邊叫數(shù)據(jù)構(gòu)造师坎,有兩個參數(shù)時數(shù)據(jù)構(gòu)造名稱可以放中間恕酸,數(shù)據(jù)構(gòu)造按是否指定字段名分兩種格式
-- record格式每個字段名自身是一個函數(shù) 類型為 數(shù)據(jù)構(gòu)造 -> 字段類型,所以訪問對象字段的格式:(字段名 對象名)
data Quadratic = Quadratic {a :: Double, b :: Double, c :: Double}
deriving Show
-- 定義類型別名 相當于c++中的 typedef/using
type RootT = Complex Double
-- 定義數(shù)據(jù)類型:只指明字段類型胯陋,沒有字段名稱
data Roots = Roots RootT RootT
deriving Show
-- 定義函數(shù)頭
roots :: Quadratic -> Roots
-- 定義函數(shù)體
-- 模式匹配 _表示忽略具體值 error拋異常
roots (Quadratic 0 0 _) = error "不是一元二次方程"
-- let <bindings> in expression
roots (Quadratic 0.0 b c) = let root = ((-c) / b :+ 0)
in Roots root root
roots (Quadratic a b c) = let discriminant = b * b - 4 * a * c
in rootsInternal (Quadratic a b c) discriminant
rootsInternal :: Quadratic -> Double -> Roots
-- |之后表示模式匹配的條件蕊温,滿足條件才能匹配上然后執(zhí)行對應(yīng)的邏輯
-- 同一個語句塊必須左對齊
rootsInternal q d | d == 0 = let r = (-(b q) / 2.0 / (a q))
root = r :+ 0
in Roots root root
-- expression where <bindings>
rootsInternal q d | d < 0 = Roots (realpart :+ complexpart) (realpart :+ (-complexpart))
where plusd = -d
twoa = 2.0 * (a q)
complexpart = (sqrt plusd) / twoa
realpart = - (b q) / twoa
rootsInternal q d | d < 0 = Roots (root1 :+ 0) (root2 :+ 0)
where plusd = -d
twoa = 2.0 * (a q)
dpart = (sqrt plusd) / twoa
prefix = -(b q) / twoa
root1 = prefix + dpart
root2 = prefix - dpart
-- Main.hs
module Main where
import Quadratic
import Data.Complex
str2double :: String -> Double
str2double str = read str :: Double
main :: IO ()
main = do
print "input a"
a <- getLine
print "input b"
b <- getLine
print "input c"
c <- getLine
-- $ 函數(shù)調(diào)用順序從右往左
putStrLn $ show $ roots (Quadratic (str2double a) (str2double b) (str2double c))
4, 編譯執(zhí)行
stack build
stack exec -- hello-exe
exec.png
5遏乔, 語法非常的神奇义矛,去年一直搞不懂,現(xiàn)在再看有點明白了(可能是內(nèi)力更深了盟萨,哈哈哈)凉翻。
6, haskell采用縮進語法捻激,但是沒有python那么嚴格制轰,只要求同一個語句塊左邊對齊(?铺罢?艇挨?)。