【发布时间】:2016-01-03 10:11:46
【问题描述】:
下面的函数convert具有类型签名:
SUnit fromUnit-> SUnit toUnit ->Value fromUnit -> Value toUnit,
它具有冗余,因为相同的信息可以表示为:
Value fromUnit -> Value toUnit。
1) 有没有办法摆脱前两个参数 (SUnit fromUnit-> SUnit toUnit) ?
2) 有没有其他方法可以更优雅地编写这个简单的依赖类型程序?
3) 这个程序在 Idris 中会是什么样子?
{-# LANGUAGE GADTs,DataKinds,KindSignatures #-}
main=do
putStrLn "Hello !"
-- putStrLn $ show $ convert SCelsius SCelsius kelvinZero -- this line does not compile
putStrLn $ show $ convert SKelvin SKelvin kelvinZero -- prints Value 0.0
putStrLn $ show $ convert SKelvin SCelsius kelvinZero -- prints Value (-273.16)
newtype Value (unit::Unit) = Value Double deriving Show
data Unit = Celsius | Kelvin
data SUnit u where
SCelsius:: SUnit Celsius
SKelvin:: SUnit Kelvin
offset=273.16
convert :: SUnit fromUnit-> SUnit toUnit ->Value fromUnit -> Value toUnit
convert SCelsius SKelvin (Value tempCel) = Value $tempCel+offset
convert SCelsius SCelsius (Value tempCel) = Value $tempCel
convert SKelvin SCelsius (Value tempK) = Value $tempK-offset
convert SKelvin SKelvin (Value tempK) = Value $tempK
kelvinZero::(Value 'Kelvin)
kelvinZero= Value 0
【问题讨论】:
-
Ps,对于那些想知道如何用 Idris 编写的人,Idris 书的“3.4.3 在函数中使用隐式参数”一章似乎是答案所在。
标签: haskell dependent-type idris