- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在这样的代码中减少重复次数的公认方法是什么?
newtype Fahrenheit = Fahrenheit Double deriving (Eq)
newtype Celsius = Celsius Double deriving (Eq)
newtype Kelvin = Kelvin Double deriving (Eq)
newtype Rankine = Rankine Double deriving (Eq)
newtype Reaumure = Reaumure Double deriving (Eq)
newtype Romer = Romer Double deriving (Eq)
newtype Delisle = Delisle Double deriving (Eq)
newtype Newton = Newton Double deriving (Eq)
instance Show Fahrenheit where
show (Fahrenheit f) = show f ++ " °F"
instance Show Celsius where
show (Celsius c) = show c ++ " °C"
instance Show Kelvin where
show (Kelvin k) = show k ++ " K"
instance Show Rankine where
show (Rankine r) = show r ++ " °R"
instance Show Reaumure where
show (Reaumure r) = show r ++ " °Ré"
instance Show Romer where
show (Romer r) = show r ++ " °Rø"
instance Show Delisle where
show (Delisle d) = show d ++ " °De"
instance Show Newton where
show (Newton n) = show n ++ " N°"
class Temperature a where
increaseTemp :: a -> Double -> a
decreaseTemp :: a -> Double -> a
toFahrenheit :: a -> Fahrenheit
toCelsius :: a -> Celsius
toKelvin :: a -> Kelvin
toRankine :: a -> Rankine
toReaumure :: a -> Reaumure
toRomer :: a -> Romer
toDelisle :: a -> Delisle
toNewton :: a -> Newton
instance Temperature Fahrenheit where
increaseTemp (Fahrenheit f) n = if n < 0 then error "negative val" else Fahrenheit $ f + n
decreaseTemp (Fahrenheit f) n = if n < 0 then error "negative val" else Fahrenheit $ f - n
toFahrenheit = id
toCelsius (Fahrenheit f) = Celsius $ (f - 32) * 5 / 9
toKelvin (Fahrenheit f) = Kelvin $ (f - 32) * 5 / 9 + 273.15
toRankine (Fahrenheit f) = Rankine $ f + 458.67
toReaumure (Fahrenheit f) = Reaumure $ (f - 32) * 4 / 9
toRomer (Fahrenheit f) = Romer $ (f - 32) * 7 / 24 + 7.5
toDelisle (Fahrenheit f) = Delisle $ (212 - f) * 5 / 6
toNewton (Fahrenheit f) = Newton $ (f - 32) * 11 / 60
instance Temperature Celsius where
increaseTemp (Celsius c) n = if n < 0 then error "negative val" else Celsius $ c + n
decreaseTemp (Celsius c) n = if n < 0 then error "negative val" else Celsius $ c - n
toFahrenheit (Celsius c) = Fahrenheit $ c * 9 / 5 + 32
toCelsius = id
toKelvin (Celsius c) = Kelvin $ c + 273.15
toRankine (Celsius c) = Rankine $ c * 9/5 + 491.67
toReaumure (Celsius c) = Reaumure $ c * 4 / 5
toRomer (Celsius c) = Romer $ c * 21 / 40 + 7.5
toDelisle (Celsius c) = Delisle $ (100 - c) * 3 / 2
toNewton (Celsius c) = Newton $ c * 33 / 100
instance Temperature Kelvin where
increaseTemp (Kelvin k) n = if n < 0 then error "negative val" else Kelvin $ k + n
decreaseTemp (Kelvin k) n = if n < 0 then error "negative val" else Kelvin $ k - n
toFahrenheit (Kelvin k) = Fahrenheit $ (k - 273.15) * 9 / 5 + 32
toCelsius (Kelvin k) = Celsius $ k - 273.15
toKelvin = id
toRankine (Kelvin k) = Rankine $ k * 9 / 5
toReaumure (Kelvin k) = Reaumure $ (k - 273.15) * 4 / 5
toRomer (Kelvin k) = Romer $ (k - 273.15) * 21 / 40 + 7.5
toDelisle (Kelvin k) = Delisle $ (373.15 - k) * 3 / 2
toNewton (Kelvin k) = Newton $ (k - 273.15) * 33 / 100
-- rest of the instances omitted.
此外,在 Class 定义中,有一种方法可以将输入变量的类型限制为其中一个 Unit。即 toCelsius::a -> Celsius
,是否可以做些什么来限制 a 的值?或者它只适用于声明了实例的类型这一事实暗示了这一点。
最佳答案
主要问题似乎是单位转换,您可以使用 DataKinds
和一堆其他看起来可怕的语言扩展(仅适用于 3 个单位,但您应该能够很容易地概括这一点):
{-# LANGUAGE DataKinds,
KindSignatures,
RankNTypes,
ScopedTypeVariables,
AllowAmbiguousTypes,
TypeApplications #-}
data TemperatureUnit = Fahrenheit | Celsius | Kelvin
newtype Temperature (u :: TemperatureUnit) = Temperature Double deriving Eq
class Unit (u :: TemperatureUnit) where
unit :: TemperatureUnit
instance Unit Fahrenheit where unit = Fahrenheit
instance Unit Celsius where unit = Celsius
instance Unit Kelvin where unit = Kelvin
instance Show TemperatureUnit where
show Celsius = "°C"
show Fahrenheit = "°F"
show Kelvin = "K"
instance forall u. Unit u => Show (Temperature u) where
show (Temperature t) = show t ++ " " ++ show (unit @u)
convertTemperature :: forall u1 u2. (Unit u1, Unit u2) => Temperature u1 -> Temperature u2
convertTemperature (Temperature t) = Temperature . fromKelvin (unit @u2) $ toKelvin (unit @u1) where
toKelvin Celsius = t + 273.15
toKelvin Kelvin = t
toKelvin Fahrenheit = (t - 32) * 5/9 + 273.15
fromKelvin Celsius k = k - 273.15
fromKelvin Kelvin k = k
fromKelvin Fahrenheit k = (k - 273.15) * 9/5 + 32
然后你可以像这样使用它:
-- the explicit type signatures here are only there to resolve
-- ambiguities; In more realistic code you'd not need them as often
main = do
let (t1 :: Temperature Celsius) = Temperature 10.0
(t2 :: Temperature Fahrenheit) = Temperature 10.0
putStrLn $ show t1 ++ " = " ++ show (convertTemperature t1 :: Temperature Fahrenheit)
-- => 10.0 °C = 50.0 °F
putStrLn $ show t2 ++ " = " ++ show (convertTemperature t2 :: Temperature Celsius)
-- => 10.0 °F = -12.222222222222221 °C
这里的技巧是 DataKinds
允许我们将常规数据类型提升到类型级别,并将它们的数据构造器提升到类型级别(我理解这在现代版本中并没有什么不同) GHC 了?抱歉,我自己对这个问题有点犹豫)。然后我们只定义一个辅助类来获取单元的数据版本,这样我们就可以基于它进行调度。这使我们能够像您尝试使用所有新类型包装器那样做,除了更少的新类型包装器(以及更少的实例声明和更少的命名函数)。
当然,另一件事是不同单位转换之间的组合爆炸式增长 - 您可以接受并手动编写所有 n^2
公式,或者您可以尝试概括它(根据@chepner 的评论,温度单位可能是可能的,但我不确定你可能想要在它们之间转换的各种事物是否可能)。这种方法无法解决该固有问题,但它确实消除了您使用 newtype
-per-unit 方法产生的一些句法噪音。
您的 increaseTemp
和 decreaseTemp
函数可以作为单个函数 offsetTemperature
实现,同时允许负数。尽管我认为让它们采用与第二个参数相同的单位而不只是 Double
更有意义:
offsetTemperature :: Temperature u -> Temperature u -> Temperature u
offsetTemperature (Temperature t) (Temperature offset) = Temperature (t + offset)
PS:Temperature 可能不是Eq
的一个实例 - 浮点相等性是出了名的不稳定(可预测,但可能不会做你想做的事)。我只是把它放在这里,因为它在你的例子中。
关于Haskell:减少样板文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55924593/
我正在创建一个 SSO 服务器,以将所有用户集中在 ActiveDirectory(AD) 中并在那里管理他们,而不是每个特定应用程序的数据库。 为了制作这个服务器,我使用了 IdentityServ
几天前,我了解了 HTML5 样板文件,所以我还是个新手。我正在尝试使用样板进行试验,所以我继续下载了这个 boilerplate 但我对下载选项的差异感到困惑。 有一个用于下载现成的自定义文件的按钮
在Flutter中,我们需要为在dispose()中创建的许多内容写下State,例如 final _nameController = TextEditingController(); @ov
我正在开发一个更大的项目,我对空检查有点厌倦。我有一个 MongoDB 实体(文档),该实体引用了另一个文档。几乎在每种情况下,我都会检查它是否为空,如果不是则执行某些操作。我知道 Java 8 中有
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
每次我向项目中添加新表单时,它都会在 use 子句中删除一大堆样板文件。 uses Windows, Messages, SysUtils, Variants, Classes, Graphics
这是我的Todo应用程序的基本结构,看起来像是“main.go”; package main import ( "encoding/json" "fmt" "log"
我有一个实现接口(interface)的类。还有另一个类也实现了这个接口(interface),并且第二个类的实例支持我的类的实现。 对于接口(interface)指定的许多方法,我的类只是将它们直接
每次我想要一个 SeekBar 和一个相应的 TextView 来显示它的数值时,为了减少代码的编写,我编写了以下抽象类: abstract public class SeekBarWrapper {
我正在考虑使用 CSS 样板(kube 或任何其他)来构建我的表单。它们在示例 html 文件中工作得很好,但是如果我想在不受控制的环境中使用(意味着 css 不在我的控制范围内),它会弄乱这些样式。
我很难在 CSS 中显示我的背景图片。我创建了一个带有 .top 类的 div,但每次我使用 background-image css 属性时,除了颜色、高度和宽度外什么都没有显示。我还使用 Init
尝试使用yarn导入react-image-crop包并将其添加到react样板中。 安装包后出现此错误 Module parse failed: /Users/...../frontend/node
我正在使用 skeleton 构建网站框架,使用 a fork that compiles from LESS . 在不丢失骨架提供的底层脚手架的情况下自定义样式的正确方法是什么?我知道我可以更改变量
从开箱即用的 HTML5 样板安装中,我使用以下代码 body { background-image:url('img/bg.png'); background-repeat:repeat-y; }
我正在使用 GWT 事件和地点框架来构建我的应用程序,结果很好。让我烦恼的一件事是 ActivityMapper实现是 (1) 接收应用程序中的所有 View (2) 包含一个巨大的 if/else
我正在使用generator-babel-boilerplate然后运行npm run test-browser。这可以正常工作,但我需要在浏览器中测试一些内容,并且我不确定如何查看正在提供的内容。
我经常使用以下样板,并希望将其消除。它看起来像这样: type Configured = ReaderT Config doSomething :: Configured IO Data doSome
我正在使用 ASP.NET 样板。我有一个 Angular 应用程序(ABP 外部),我想使用我的 API。 为此,我通过 /api/TokenAuth/Authenticate 获取访问 token
我的 JS 为: (function () { var controllerId = 'app.views.dashboard'; angular.module('app').cont
我们曾经可以输入 !在 vscode 中的 html 文档中获取 html boiler plate content completion as documented here . 然而它不再起作用。
我是一名优秀的程序员,十分优秀!