1. 程式人生 > >十分鐘學會 Haskell

十分鐘學會 Haskell

1 概要

Haskell 是函式式(一切通過函式呼叫來完成)、靜態、隱式型別(型別由編譯器檢測,型別宣告不是必需的)、惰性(除非必要,否則什麼也不做)的語言。其最大眾化的近親大概是 ML 族語言(不過不是惰性的)。

最流行(common)的 Haskell 編譯器是 GHC下載地址。GHC 在 GNU/LinuxFreeBSDMacOSWindows 以及 Solaris 平臺上都有可供使用的二進位制包。安裝 GHC,即獲得 ghc 和 ghci。前者用於將 Haskell 程式庫或應用程式編譯成二進位制碼。後者為直譯器,可在編寫 Haskell 程式碼後立即得到反饋.

2 表示式

大部份數學表示式都可以輸入 ghci

 直接解答。Prelude> 是 GHCi 預設提示符。

Prelude> 3 * 5
 15
Prelude> 4 ^ 2 - 1
 15
Prelude> (1 - 5)^(3 * 2 - 4)
 16
字串需要雙引號引用,以 ++ 連線。 Prelude> "Hello"
 "Hello"
Prelude> "Hello" ++ ", Haskell"
 "Hello, Haskell"

呼叫函式時,引數緊接函式即可,其間無須新增括號。

Prelude> succ 5
 6
Prelude> truncate 6.59
 6
Prelude> round
 6.59
 7
Prelude> sqrt 2
 1.4142135623730951
Prelude> not (5 < 3)
 True
Prelude> gcd 21 14
 7

3 控制檯

呼叫 I/O actions 進行控制檯輸入和輸出。如:

Prelude> putStrLn "Hello, Haskell"
 Hello, Haskell
Prelude> putStr "No newline" No newlinePrelude> print (5 + 4)
 9
Prelude> print (1 < 2)
 True
putStr 和 putStrLn
 輸出字串到終端。print 輸出任意型別的值。(如果 print 作用於字串,輸出將用引號引用。) 複雜的 I/O acttions 需要 do 語句塊,以分號間隔。 Prelude> do { putStr "2 + 2 = " ; print (2 + 2) }
 2 + 2 = 4
Prelude> do { putStrLn "ABCDE" ; putStrLn "12345" }
 ABCDE
 12345
通過 getLine(返回字串)或 readLn(返回任意你需要的型別)獲得輸入。用 <- 符號給 I/O action 的結果命名。 Prelude> do { n <- readLn ; print (n^2) }
 4
 16

(4 是輸入。16 是結果。)

do 語句塊的另一種方式,以縮排取代花括號和分號。雖然在 ghci 中未能獲得完美支援,但是可以把它們塞進原始檔(如 Test.hs)裡然後編譯:
main = do putStrLn "What is 2 + 2?"
          x <- readLn
          if x == 4
              then putStrLn "You're right!"
              else putStrLn "You're wrong!"

執行 ghc --make Test.hs,得到 Test(Windows 上是 Test.exe)。順便接觸了 if 語句。

do 之後首個非空白字元,如上例 putStrLn 的 p,是特別的。每新起一行,行首與之對齊,即視為同一 do 塊之新句;縮排較之多則繼續前句;較之少則結束此 do 塊。是為頁面佈局(layout),Haskell 以之迴避語句結束標記和花括號。(故then 和 else 子句務必縮排,否則將脫離 if 語句,導致錯誤。)

(注意:切勿使用製表符。從技術上講,八格製表符可以正常工作,但不是個好主意。也不要使用非等寬字型——顯然,有些人在程式設計的時候會犯此糊塗!)

4 型別

到目前為止,我們一直沒有提到過型別宣告。那是因為 Haskell 暗中推斷,不必宣告之。如果非要宣告型別,可用 :: 符號明確指出,如: Prelude> 5 :: Int
 5
Prelude> 5 :: Double
 5.0

型別 types(以及型別類 type classes,稍後提及)總是以大寫開頭。變數(variables)總是以小寫開頭。這是語言規則,而不只是命名習慣

你也可以讓 ghci 告訴你選擇的內容的型別,這種方法很有用,因為型別宣告並不是必需的。

Prelude> :t True True :: Bool Prelude> :t 'X' 'X' :: Char Prelude> :t "Hello, Haskell" "Hello, Haskell" ::[Char] (在這個例子中,[Char] 是 String 的另外一種表達方式。參見後面的 section on lists 。)

有關數字的例子則更加有趣:

Prelude> :t 42 42 :: (Num t) => t Prelude> :t 42.0 42.0 :: (Fractional t) => t Prelude> :t gcd 15 20 gcd 15 20:: (Integral t) => t

這些型別用到了 "型別類(type classes)" 含義如下:

  • 42 可作為任意數字(numeric)型別。(這就是為什麼我既可以把5宣告為Int型別,也可以宣告為Double型別的原因。)
  • 42.0 可作為任意分數(fractional)型別,但不能是整數(integral)型別。
  • gcd 15 20 (此為函式呼叫) 可作為任意整數(integral)型別,但不能是分數型別。

在Haskell "Prelude"(你不需要import任何東西就能使用的那部分庫)中有五種數字(numeric)型別:

  • Int 是一個至少30位(bit)精度的整數。
  • Integer 是一個無限精度的整數。
  • Float 是一個單精度浮點數。
  • Double 是一個雙精度浮點數。
  • Rational 是一個沒有舍入誤差的分數/小數型別。
上面5個都是Num型別的例項(instances)。其中前兩個是Integral型別的例項,後面三種是Fractional型別的例項

總的一塊來看一下,

Prelude> gcd 42 35 :: Int
 7
Prelude> gcd 42 35 :: Double
 <interactive>:1:0:
     No instance for (Integral Double)
最後值得一提的型別是(),念做"unit"。 它只有一個取值,也寫作()並念做"unit"。 Prelude> () () Prelude> :t ()() :: () 你可以把它看作類似C語言中的void關鍵字。在一個I/O動作中,如果你不想返回任何東西,你可以返回()

5 有結構的資料

基本資料型別可以很容易的通過兩種方式組合在一起:通過 [方括號] 組合的列表(lists),和通過 (圓括號) 組合的元組(tuples)

列表可以用來儲存多個相同型別的值:

Prelude> [123]
 [1,2,3]
Prelude> [1 .. 5]
 [1,2,3,4,5]
Prelude> [13 .. 10]
 [1,3,5,7,9]
Prelude> [True, False, True]
 [True,False,True]

Haskell 中的字串(String)其實只不過是字元(Character)型別的 List:

Prelude> ['H', 'e', 'l', 'l', 'o']
 "Hello"
冒號 : 運算子用來把一個項(item)新增到列表的開始處。(相當於LISP語言中的cons函式) Prelude> 'C' :['H', 'e', 'l', 'l', 'o']
 "CHello"

元組則和列表不同,它用來儲存固定個數,但型別不同的值。【譯者注:列表是型別相同,但個數不固定,甚至還可以是無限個數】

Prelude> (1, True)
 (1,True)
Prelude> zip [1 .. 5] ['a' .. 'e']
 [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')]
上面這個例子用到了 zip 函式,它可以把兩個列表組合成一個元組的列表。

型別一般都符合你的期望:

Prelude> :t ['a' .. 'c'] ['a' .. 'c'] :: [Char] Prelude> :t [('x', True)('y', False)] [('x', True)('y', False)] :: [(CharBool)]

列表在Haskell中被大量使用。有些函式能夠很好地對列表進行運算:

Prelude> [1 .. 5] [1,2,3,4,5] Prelude> map (+ 

相關推薦

分鐘學會 Haskell

1 概要Haskell 是函式式(一切通過函式呼叫來完成)、靜態、隱式型別(型別由編譯器檢測,型別宣告不是必需的)、惰性(除非必要,否則什麼也不做)的語言。其最大眾化的近親大概是 ML 族語言(不過不是惰性的)。最流行(common)的 Haskell 編譯器是 GHC,下載地址。GHC 在 GNU/Linu

3) 分鐘學會android--建立第一個APP,建立簡單的用戶界面

使用 圖標 run class 屏幕寬度 情況下 不可見 文本輸入框 nes 在本小節裏,我們將學習如何用 XML 創建一個帶有文本輸入框和按鈕的界面。下一節課將學會使 APP 對按鈕做出響應——按鈕被按下時,文本框裏的內容被發送到另外一個 Acti

8) 分鐘學會android--Activity的生命周期之停止與重啟

圖標 getc uid contex ont progress 部分 重啟 settings 恰當的停止與重啟我們的activity是很重要的,在activity生命周期中,他們能確保用戶感知到程序的存在並不會丟失他們的進度。在下面一些關鍵的場景中會涉及到停止與重啟:

(轉)大資料處理之道(分鐘學會Python)

轉自:http://blog.csdn.net/u010700335/article/details/42025391,如侵刪 (0)目錄 快速學Python 和 易犯錯誤(文字處理) Python文字處理和Java/C比對 十分鐘學會Python的基本型別 快速學會Python(

分鐘學會Flask

什麼是Flask Flask是一個基於Python並且依賴於Jinja2模板引擎和Werkzeug WSGI服務的一個微型框架 Flask中包含一個輕量級的web 伺服器主要用於在開發階段測試使用 Falsk使用MTV框架模式 MTV框架模式 M : Models , 模型層 ,

分鐘學會】正則表示式字元匹配攻略

閱讀建議:看一下正則表示式基礎,有一定的基本概念,效果最佳。 正則表示式是匹配模式,要麼匹配字元,要麼匹配位置。請記住這句話。 然而關於正則如何匹配字元的學習,大部分人都覺得這塊比較雜亂。 畢竟元字元太多了,看起來沒有系統性,不好記。本

分鐘學會Python函數語言程式設計

    函數語言程式設計到底是什麼?本文將詳解其概念,同時分享怎樣在 Python 中使用函數語言程式設計。主要內容包括列表解析式和其他形式的解析式。 函式式模型     在命令式模型中,執行程式的方式是給計算機一系列指

分鐘學會函式式 Python!

    函數語言程式設計到底是什麼?本文將詳解其概念,同時分享怎樣在 Python 中使用函數語言程式設計。主要內容包括列表解析式和其他形式的解析式。 函式式模型 在命令式模型中,執行程式的方式是給計算機一系列指令讓它執行。執行過程中計算機會改變狀態。例如,

分鐘學會Java8新特性:lambda表示式和Stream API

Java8 的新特性:Lambda表示式、強大的 Stream API、全新時間日期 API、ConcurrentHashMap、MetaSpace。總得來說,Java8 的新特性使 Java 的執行速度更快、程式碼更少、便於並行、最大化減少空指標異常。 這篇文章分享之前我還是要推薦下我

分鐘學會Markdown語法

Markdown 語法介紹Markdown 是一種輕量級標記語言,讓寫作者專注於寫作而不用關注樣式。Coding 的許多版塊均採用了 Markdown 語法,比如冒泡、討論、Pull Request 等。標題用 Markdown 書寫時,只需要在文字前面加上『# 』即可建立一

分鐘學會 tmux

# 開啟滑鼠模式 set -g mode-mouse on ​ # 允許滑鼠選擇窗格 set -g mouse-select-pane on ​ # 如果喜歡給視窗自定義命名,那麼需要關閉視窗的自動命名 set-option -g allow-rename off ​ # 如果對 vim

Python 分鐘學會pandas基本資料操作

importIn[1]: import numpy as np In[2]: import pandas as pd In[3]: import matplotlib.pyplot as plt 建立物件通過list建立Series,pandas建立預設的整數索引In[4]: s = pd.Series

分鐘學會Fiddler

一.Fiddler介紹 Fiddler是一個http抓包改包工具,fiddle英文中有“欺騙、偽造”之意,與wireshark相比它更輕量級,上手簡單,因為只能抓http和https資料包,所以在針對http和https資料包的抓取上它更加專業。 不僅可以記錄客戶端和

分鐘學會正則表示式

1、正則表示式 正則表示式(regular expression)描述了一種字串匹配的模式,可以用來檢查一個串是否含有某種子串、將匹配的子串做替換或者從某個串中取出符合某個條件的子串等。 模式:使用一種特殊符號來實現字串的匹配 2、建立正則物件 ①隱式建立 var 正則物件

分鐘學會Charles抓包(iOS的http/https請求)

Charles安裝HTTP抓包HTTPS抓包1. Charles安裝2. HTTP抓包(1)檢視電腦IP地址(2)設定手機HTTP代理手機連上電腦,點選“設定->無線區域網->連線的WiFi”,設定HTTP代理:伺服器為電腦IP地址:如192.168.1.169埠:8888設定代理後,需要在電腦上

分鐘學會Python的基本型別

一:起因 (1)說起學習Python的原因,上一篇blog已經提到過了;Python掐指一算不過是自己接觸過的第四門大型語言(從接觸到現在已經2周了)c/c++ ,Java,MATLAB(PS:應該還不算入門,只會簡單的應用),之後就是python了。 (2)c/c++ 到

分鐘學會Scratch圖形化程式設計

一、概要 Scratch是麻省理工學院開發的供兒童或者初學者學習程式設計的開發平臺。其通過點選並拖拽的方式,完成程式設計,可以使兒童或者成人程式設計初學者學習程式設計基礎概念等。Scratch是一款積木式圖形程式設計軟體。 授權協議:GPLv2 開發語言:C/C++ 官網地址:https://scratch

【轉載】分鐘一起學會ResNet殘差網路

  深層次網路訓練瓶頸:梯度消失,網路退化 深度卷積網路自然的整合了低中高不同層次的特徵,特徵的層次可以靠加深網路的層次來豐富。從而,在構建卷積網路時,網路的深度越高,可抽取的特徵層次就越豐富。所以一般我們會傾向於使用更深層次的網路結構,以便取得更高層次的特徵。但是在使用深層次的網路結構時我們會

分鐘學會的技巧

1,在紙上寫下 3 個你在 3 年內最想實現、願意為之努力的願望(出國讀書、買新電腦、買遊戲機、學好程式設計、改頭換面、鍛鍊身體……) 2,貼在自己每天都能看到的地方,比如顯示器下方,如果不想別人看可以貼在家裡的顯示器下 人在重複的環境中會懈怠、失去目標,這樣可以確保自己不忘初心,不讓時光被偷偷吃掉。

分鐘學會的簡單python爬蟲

簡單爬蟲三步走,So easy~ 本文介紹一個使用python實現爬蟲的超簡單方法,精通爬蟲挺難,但學會實現一個能滿足簡單需求的爬蟲,只需10分鐘,往下讀吧~ 該方法不能用於帶有反爬機制的頁面,但對於我這樣的非專業爬蟲使用者,幾乎遇到的各種簡單爬蟲需求都是可