3
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

# 列挙型

【問1】光の三原色と、2つの色を混合する関数`mix`を定義してください。混ぜることによってできる色も定義の対象とします。ただし同じ成分同士は強め合わないものとします。

``````data Color = Blue | Red | Magenta | Green | Cyan | Yellow | White
deriving (Show, Eq)

mix Blue    Red       = Magenta
mix Blue    Magenta   = Magenta
mix Blue    Green     = Cyan
mix Blue    Cyan      = Cyan
mix Blue    Yellow    = White
mix Red     Magenta   = Magenta
mix Red     Green     = Yellow
mix Red     Cyan      = White
mix Red     Yellow    = Yellow
mix Magenta Green     = White
mix Magenta Cyan      = White
mix Magenta Yellow    = White
mix Green   Cyan      = Cyan
mix Green   Yellow    = Yellow
mix Cyan    Yellow    = White
mix White   _         = White
mix c1 c2 | c1 == c2  = c1
| otherwise = mix c2 c1

main = do
print \$ mix Blue Blue
print \$ mix Red Blue
print \$ mix Red \$ mix Blue Green
``````

``````Blue
Magenta
White
``````

## 別解

ビット演算で簡単に書けます。

``````import Data.Bits

data Color = Black | Blue | Red | Magenta | Green | Cyan | Yellow | White
deriving (Show, Enum)

mix c1 c2 = toEnum (fromEnum c1 .|. fromEnum c2) :: Color

main = do
print \$ mix Red Blue
print \$ mix Red \$ mix Blue Green
``````

``````Magenta
White
``````

# 直積型

【問2】x,y,w,hを表現した`Rect`型を定義して、`Rect``Point`が含まれるかどうかを判定する関数`contains`を実装してください。

``````data Point = Point Int Int deriving Show
data Rect = Rect Int Int Int Int deriving Show

contains (Rect x y w h) (Point px py) =
x <= px && px < x + w && y <= py && py < y + h

main = do
print \$ contains (Rect 2 2 3 3) (Point 1 1)
print \$ contains (Rect 2 2 3 3) (Point 2 2)
print \$ contains (Rect 2 2 3 3) (Point 3 3)
print \$ contains (Rect 2 2 3 3) (Point 4 4)
print \$ contains (Rect 2 2 3 3) (Point 5 5)
``````

``````False
True
True
True
False
``````

# 直和型

【問3】`Rect``Point`を2次元と3次元の両方に対応させて、問2の`contains`も対応させてください。

``````data Point = Point   Int Int
| Point3D Int Int Int
deriving Show

data Rect = Rect   Int Int Int Int
| Rect3D Int Int Int Int Int Int
deriving Show

contains (Rect x y w h) (Point px py) =
x <= px && px < x + w && y <= py && py < y + h

contains (Rect3D x y z w h d) (Point3D px py pz) =
x <= px && px < x + w &&
y <= py && py < y + h &&
z <= pz && pz < z + d

main = do
print \$ contains (Rect 2 2 3 3) (Point 1 1)
print \$ contains (Rect 2 2 3 3) (Point 2 2)
print \$ contains (Rect 2 2 3 3) (Point 3 3)
print \$ contains (Rect 2 2 3 3) (Point 4 4)
print \$ contains (Rect 2 2 3 3) (Point 5 5)
print \$ contains (Rect3D 2 2 2 3 3 3) (Point3D 1 1 1)
print \$ contains (Rect3D 2 2 2 3 3 3) (Point3D 2 2 2)
print \$ contains (Rect3D 2 2 2 3 3 3) (Point3D 3 3 3)
print \$ contains (Rect3D 2 2 2 3 3 3) (Point3D 4 4 4)
print \$ contains (Rect3D 2 2 2 3 3 3) (Point3D 5 5 5)
``````

``````False
True
True
True
False
False
True
True
True
False
``````

# レコード構文

【問4】問2の解答をレコード構文で書き直してください。

``````data Point = Point { px :: Int, py :: Int } deriving Show
data Rect  = Rect  { rx :: Int, ry :: Int, rw :: Int, rh :: Int } deriving Show

contains r p =
(rx r) <= (px p) && (px p) < (rx r) + (rw r) &&
(ry r) <= (py p) && (py p) < (ry r) + (rh r)

main = do
print \$ contains Rect { rx = 2, ry = 2, rw = 3, rh = 3 } Point { px = 1, py = 1 }
print \$ contains Rect { rx = 2, ry = 2, rw = 3, rh = 3 } Point { px = 2, py = 2 }
print \$ contains Rect { rx = 2, ry = 2, rw = 3, rh = 3 } Point { px = 3, py = 3 }
print \$ contains Rect { rx = 2, ry = 2, rw = 3, rh = 3 } Point { px = 4, py = 4 }
print \$ contains Rect { rx = 2, ry = 2, rw = 3, rh = 3 } Point { px = 5, py = 5 }
``````

``````False
True
True
True
False
``````
Why not register and get more from Qiita?
1. We will deliver articles that match you
By following users and tags, you can catch up information on technical fields that you are interested in as a whole
2. you can read useful information later efficiently
By "stocking" the articles you like, you can search right away