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 IOException
MutableIO
是 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 !