Frege #0
想在工作用得上的 side-project 裡試試 Frege 。初衷是:如果大家都在 production 用 FP language ,我也必須這樣。不然經驗永遠不夠,只能把 FP 當玩具。
Frege: Hello Java - mmhelloworld 介紹了如何用 Frege 跟 Java 溝通,可以看到不純的 class 要放在長長的 ST s (Mutable s (ClassName a)) 中,可以簡寫成 STMutable s (ClassName a) 。
ST s a 的說明可以在 PreludeBase.fr 中找到:
@(ST s a)@ is an abstract data type and is a computation that encapsulates side effects in state thread @s@ and returns a value of type @a@.
配上 talios/frege-testing ,只靠 mvn compile exec:exec 就把程式跑起來!
Frege 社群有個工具, Frege/frege-native-gen ,能幫忙自動產生和 Java classes 溝通的程式碼,但我打算先自己寫幾次,了解 ST s a 到底是什麼、用起來是什麼感覺後,再學工具。
接接看 Apache.POI
來看看要怎麼包 HSSFWorkbook 這種實用的 lib 。
首先我們需要把 Java constructor 包起來:
data HSSFWorkbook = native org.apache.poi.hssf.usermodel.HSSFWorkbook where
native new :: () -> ST s (Mutable s HSSFWorkbook)其中 ST s (Mutable s HSSFWorkbook) 可以簡寫為 STMutable s HSSFWorkbook ,兩個 s 的 type 相同:
data HSSFWorkbook = native org.apache.poi.hssf.usermodel.HSSFWorkbook where
native new :: () -> STMutable s HSSFWorkbook接著處理 HSSFWorkbook::write :
data HSSFWorkbook = native org.apache.poi.hssf.usermodel.HSSFWorkbook where
native new :: () -> STMutable s HSSFWorkbook
native write :: MutableIO HSSFWorkbook -> OutputStream -> IO ()
throws IOExceptionMutableIO 是 Mutable RealWorld 的別名, IO 是 ST RealWorld 的別名。還有個現在沒出現的 IOMutable 是 IO MutableIO 的別名。
接著還需要產生 HSSFSheet ,在 HSSFWorkbook 中加上 createSheet function :
data HSSFWorkbook = native org.apache.poi.hssf.usermodel.HSSFWorkbook where
native new :: () -> STMutable s HSSFWorkbook
native createSheet :: Mutable s HSSFWorkbook -> String -> STMutable s HSSFSheet
native write :: MutableIO HSSFWorkbook -> OutputStream -> IO ()
throws IOException補上其他 type :
data HSSFSheet = native org.apache.poi.hssf.usermodel.HSSFSheet where
native createRow :: Mutable s HSSFSheet -> Int -> STMutable s Row
data Cell = native org.apache.poi.ss.usermodel.Cell where
native setCellValue :: Mutable s Cell -> String -> ST s ()
data Row = native org.apache.poi.ss.usermodel.Row where
native createCell :: Mutable s Row -> Int -> STMutable s Cell處理一下例外:
pure native showThrowable toString :: Throwable -> String整個寫起來像這樣:
module frege.Main where
data HSSFSheet = native org.apache.poi.hssf.usermodel.HSSFSheet where
native createRow :: Mutable s HSSFSheet -> Int -> STMutable s Row
data HSSFWorkbook = native org.apache.poi.hssf.usermodel.HSSFWorkbook where
native new :: () -> STMutable s HSSFWorkbook
native createSheet :: Mutable s HSSFWorkbook -> String -> STMutable s HSSFSheet
native write :: MutableIO HSSFWorkbook -> OutputStream -> IO ()
throws IOException
data Cell = native org.apache.poi.ss.usermodel.Cell where
native setCellValue :: Mutable s Cell -> String -> ST s ()
data Row = native org.apache.poi.ss.usermodel.Row where
native createCell :: Mutable s Row -> Int -> STMutable s Cell
pure native showThrowable toString :: Throwable -> String
main _ = do
let filename = "out.xls"
workbook <- HSSFWorkbook.new ()
sheet <- HSSFWorkbook.createSheet workbook filename
row <- HSSFSheet.createRow sheet 0
cell <- Row.createCell row 0
Cell.setCellValue cell "hello, world"
file <- File.new filename
out <- FileOutputStream.new file
try (\book -> HSSFWorkbook.write book out) workbook
`catch` (\(exception :: IOException) -> println $ showThrowable exception)再來要挑戰 Vert.x !