常量在Haskell中是多态的。所以当我写:
foo = 5
这令人厌恶:
foo = fromInteger 5
但是如果添加算术表达式呢?
foo = 42 - 15
究竟是什么会被贬低?
foo = fromInteger (42 - 15)
或
for = fromInteger 42 - fromInteger 15
此外,观察此事的最简单可靠的方法是什么?
答案 0 :(得分:5)
Haskell具有多态文字。 (默认只是数字,但GHC具有多态字符串文字和多态列表文字的语言扩展)
强制表达式(如fromInteger
)仅对文字本身起作用,而不是表达式,所以
foo = 42 - 15
和
foo = fromInteger 42 - fromInteger 15
是等价的。
我们可以通过定义行为不同的Num
实例来展示这种情况(例如,交换+
和-
的地方)
newtype Inverted a = Inverted {unInvert :: a}
deriving (Eq, Ord, Show)
instance (Num a) => Num (Inverted a) where
(Inverted x) + (Inverted y) = Inverted (x-y)
(Inverted x) - (Inverted y) = Inverted (x+y)
signum = Inverted . signum . unInvert
(Inverted x) * (Inverted y) = Inverted (x*y)
abs = Inverted . abs . unInvert
fromInteger = Inverted . fromInteger
base :: Inverted Double
base = 42 - 15
fromBeforeOp :: Inverted Double
fromBeforeOp = fromInteger 42 - fromInteger 15
fromAfterOp :: Inverted Double
fromAfterOp = fromInteger (42 - 15)
base
和fromBeforeOp
都给Inverted
的{{1}}答案提供了相同的内容(57
的定义是正确的),fromAfterOp
给出了27
templacte <T, Base>
class ThrowIfNotBaseOf {
void checkIt() {
if(!std::is_base_of<Base, T>::value) {
throw std::invalid_argument( "T must inherit from Time Class" );
}
}
public:
TypeCheckThrow() { // default constructor
checkIt();
}
TypeCheckThrow(const TypeCheckThrow<T, Base> &) { // copy constructor
checkIt();
}
TypeCheckThrow(TypeCheckThrow<T, Base> &&) { // move constructor
checkIt();
}
};
template<class T>
class B
{
ThrowIfNotBaseOf<T, Time> typeCheckThrow;
T data;
void do_someting()
{
data.t = 12.34;
}
};
}}
答案 1 :(得分:3)
很沮丧
foo = fromInteger 42 - fromInteger 15
您可以通过尝试
来观察f :: Double -> Int -> String
f _ _ = "hello"
foo = 42 `f` 15
我们使用自定义f
代替-
。在调用f
之前,必须将这两个文字转换为数字类型。转换f
的结果将毫无意义,因为它不是数字类型。
使用-
不会改变一般规则。