我想要一个12小时的幺半。
data Clock12Hours = Clock12Hours Int
deriving (Show)
instance Monoid Clock12Hours where
mappend (Clock12Hours x) (Clock12Hours y) = Clock12Hours $ (x + y) `mod` 12
mempty = Clock12Hours 12
当我mappend (Clock12Hours 4) (Clock12Hours 10)
时,我得到了正确的价值 - Clock12Hours 2
。
我的问题是:
fmap (id) Clock12Hours 10
时,我得到Clock12Hours 10
。但是,如果我没有提供一个仿函数定义(在评论中澄清,甚至无法完成),它如何知道如何fmap?fmap (+1) (Clock12Hours 10)
时出现错误No instance for (Num Clock12Hours) arising from a use of ‘+’
- 为什么会这样?fmap (+4) (Clock12Hours 10)
将返回Clock12Hours 2
。如何?答案 0 :(得分:3)
我认为你打算做这样的事情:
{-# LANGUAGE Safe #-}
module Numeric.IntMod12 (
IntMod12(), lift1Enum, lift2Enum
) where
newtype IntMod12 = IntMod12 Int deriving (Eq, Ord, Show)
instance Enum IntMod12 where
{-# INLINABLE toEnum #-}
toEnum i = IntMod12 (mod i 12)
{-# INLINABLE fromEnum #-}
fromEnum (IntMod12 i) = i
lift1Enum :: (Enum a, Enum b) => (Int -> Int) -> a -> b
{-# INLINABLE lift1Enum #-}
lift1Enum f = \ x -> toEnum (f (fromEnum x))
lift2Enum :: (Enum a, Enum b, Enum c) => (Int -> Int -> Int) -> a -> b -> c
{-# INLINABLE lift2Enum #-}
lift2Enum f = \ x y -> toEnum (f (fromEnum x) (fromEnum y))
instance Real IntMod12 where
{-# INLINABLE toRational #-}
toRational (IntMod12 i) = toRational i
instance Num IntMod12 where
{-# INLINABLE fromInteger #-}
fromInteger i = IntMod12 (fromInteger (mod i 12))
(+) = lift2Enum (+)
(-) = lift2Enum (-)
(*) = lift2Enum (*)
negate = lift1Enum negate
abs = id
signum 0 = 0
signum _ = 1
instance Integral IntMod12 where
{-# INLINABLE toInteger #-}
toInteger (IntMod12 i) = toInteger i
div = lift2Enum div
mod = lift2Enum mod
quot = lift2Enum quot
rem = lift2Enum rem
divMod x y = (toEnum d, toEnum m) where
(d, m) = divMod (fromEnum x) (fromEnum y)
quotRem x y = (toEnum q, toEnum r) where
(q, r) = quotRem (fromEnum x) (fromEnum y)
instance Monoid IntMod12 where
mempty = 0
mappend = (+)
由于这不是Functor
(并且无法转换为Functor
),因此您必须使用lift1Enum
而不是fmap
之类的内容。
答案 1 :(得分:0)
我对1.
没有答案,因为我无法重现GHC 7.10.3上的错误。
对于2.
:只有采用1个类型参数构建的类型才能成为仿函数,因为fmap
在其参数中是多态,而Clock12Hours
则不是。3.
。
回答myMap :: (Int -> Int) -> Clock12Hours -> Clock12Hours
myMap f (Clock12Hours time) = Clock12Hours (f time)
:地图操作解压缩它的参数,应用函数并重新打包整个事物。使用这个定义,我们提出:
mappend mempty
但现在我们遇到的问题是我们可能无法获得12小时的时间,因此我们有两个选择:添加0(normalize
)或编写normalize (Clock12Hours x) = Clock12Hours (x `mod` 12)
normalize clock = myMap (`mod` 12) clock
normalize = myMap (`mod` 12)
函数:
private void button1_Click(object sender, EventArgs e)
{
Form2 f2= new Form2();
if(condition==true)
{
this.Hide();
f2.ShowDialog();
this.Close();
}
}