haskell求解一元二次方程

灰暗已經(jīng)過去,又開始寫文章啦啦啦!??!

1, 之前學(xué)習(xí)大數(shù)據(jù)要用到scala語(yǔ)言,遇到scala里面的函數(shù)式部分有點(diǎn)懵逼。后來就想深入學(xué)習(xí)一下函數(shù)式語(yǔ)言。現(xiàn)在的很多命令式語(yǔ)言都支持函數(shù)式風(fēng)格,但是因?yàn)槊钍降乃枷敫畹俟潭嗄旰芏嗪瘮?shù)式的思想很難理解。于是就想直接從一門純粹的函數(shù)式語(yǔ)言入手從零開始學(xué)習(xí)函數(shù)式編程思想。去年在工作空閑時(shí)花過一段時(shí)間學(xué)習(xí)haskell,當(dāng)時(shí)有點(diǎn)暈,很多東西沒搞明白,后來事情太多中斷了。如今有空了,再繼續(xù)吧。

本文先從Haskell Cookbook上的求解一元二次方程開始吧,熟悉一下語(yǔ)法。

2, 配置環(huán)境:按照haskell文檔安裝stack,別用brew install stack,版本太舊,問題多多。
haskell官方IDE是基于eclipse的,不太好用,目前直接使用vs code。

3, stack new hello新建工程。

項(xiàng)目結(jié)構(gòu).png
-- Quadratic.hs
module Quadratic where

-- 導(dǎo)入模塊
import Data.Complex

-- 定義數(shù)據(jù)類型:record格式
-- =號(hào)左邊叫類型構(gòu)造,可以接受類型參數(shù),相當(dāng)于定義泛形類型
-- =號(hào)右邊叫數(shù)據(jù)構(gòu)造,有兩個(gè)參數(shù)時(shí)數(shù)據(jù)構(gòu)造名稱可以放中間,數(shù)據(jù)構(gòu)造按是否指定字段名分兩種格式
-- record格式每個(gè)字段名自身是一個(gè)函數(shù) 類型為 數(shù)據(jù)構(gòu)造 -> 字段類型,所以訪問對(duì)象字段的格式:(字段名 對(duì)象名)
data Quadratic = Quadratic {a :: Double, b :: Double, c :: Double}
                              deriving Show

-- 定義類型別名 相當(dāng)于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í)行對(duì)應(yīng)的邏輯
-- 同一個(gè)語(yǔ)句塊必須左對(duì)齊
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, 語(yǔ)法非常的神奇,去年一直搞不懂,現(xiàn)在再看有點(diǎn)明白了(可能是內(nèi)力更深了,哈哈哈)。

6, haskell采用縮進(jìn)語(yǔ)法,但是沒有python那么嚴(yán)格,只要求同一個(gè)語(yǔ)句塊左邊對(duì)齊(???)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 今天是第三次參加錢永靜老師的導(dǎo)師班學(xué)習(xí),不一樣的體驗(yàn)。永靜老師今天從發(fā)型、服飾搭配、眼神、手勢(shì)、形體姿態(tài)等方面,都...
    林亦凡閱讀 708評(píng)論 0 0
  • 看到孩子們很認(rèn)真的考試,猶其是我們班男生多,考試時(shí)還能很認(rèn)真這就能看出老師為此付出了多少吧,她不求回報(bào),任勞任怨,...
    冰是睡覺的水閱讀 323評(píng)論 0 0
  • 情是心的網(wǎng),我是被網(wǎng)心的情,困住了嗎?明月不了月明癡。風(fēng)雪寞寂,心在等一生,一生在等心,悠悠千心嘆,月過明媚,誰(shuí)又...
    文心雨閱讀 96評(píng)論 0 0

友情鏈接更多精彩內(nèi)容