2014-10-07 121 views
2

在許多語言中,您可以編寫'A' + i來獲取某個整數i來獲取字母表中的字母。我如何在Haskell中做到這一點? (同時,也是反向操作像let ch = 'B' in (ch - 'A')) == 1Haskell中的字符算術運算

Prelude> 'A' + 1 
    No instance for (Num Char) arising from a use of `+' 
+4

來自['Data.Char']的'ord'和'chr'(http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.1/Data-Char.html #g:6)在Int和Char之間進行轉換。 – Vektorweg 2014-10-07 17:32:44

+2

順便說一下,'Char'是['Enum']的一個實例(http://www.haskell.org/ghc/docs/latest/html/libraries/base-4.7.0.1/Prelude.html#t:枚舉)。 – MasterMastic 2014-10-07 18:56:48

回答

6

正如評論指出的那樣,你可以IntChar之間,從功能轉換Data.Char。然而這並不像你所要求的那樣含蓄。

如果你真的想這樣,你可以在理論上做出Num實例,舉例如下:

import Data.Char (chr, ord) 

instance Num Char where 
    c1 + c2 = chr (ord c1 + ord c2) 
    c1 - c2 = chr (ord c1 - ord c2) 
    fromInteger = chr . fromInteger 

然後你得到

> 'A' + 1 
'B' 

> 'B' - 'A' == 1 
True 

但是它是相當因爲Char黑客攻擊並不是一個真正的數字。

特別通知,如果你實際檢查的'B' - 'A'值會發生什麼:

> 'B' - 'A' 
'\SOH' 

即你的性格1,而不是真正看到它作爲一個Int。上面的等式檢查是可行的,因爲1被轉換爲Char,但是您沒有得到相反的隱式轉換。

我也從Num中省略了一些其他操作,所以你會得到編譯器警告,有些操作不起作用。你可以沿着同樣的路線添加它們,但它們的意義不大。

+0

美麗答案 – osager 2014-10-07 17:46:33

+0

不需要執行其他的Num Class函數,例如'signum'? – osager 2014-10-07 17:50:09

+0

我在最後一段中提到過(忍者編輯,所以你原本可能沒有看到它) - 在理論上它們是需要某些東西的,但是在'Char'上做這件事更加奇怪,所以我省略了它們解釋的目的。 – 2014-10-07 17:57:50