Nie uproszczenie logiki ręcznie (zakładając, że można generować ten kod automatycznie), myślę, że używanie MultiWayIf
jest całkiem czyste i bezpośrednie.
{-# LANGUAGE MultiWayIf #-}
data Stats = Stats {
curr_linkDensity :: Double,
prev_linkDensity :: Double,
...
}
data Classification = Content | Boilerplate
classify :: Stats -> Classification
classify s = if
| curr_linkDensity s <= 0.333333 -> if
| prev_linkDensity s <= 0.555556 -> if
| curr_numWords s <= 16 -> if
| next_numWords s <= 15 -> if
| prev_numWords s <= 4 -> Boilerplate
| prev_numWords s > 4 -> Content
| next_numWords s > 16 -> Content
...
i tak dalej.
Jednak skoro jest to tak uporządkowane - po prostu drzewo wyrażenia if/else z porównaniami, należy również rozważyć utworzenie struktury danych drzewa decyzyjnego i napisanie dla niego interpretera. Umożliwi to dokonywanie transformacji, manipulacji, inspekcji. Może ci coś kupi; określenie miniaturowych języków dla twoich specyfikacji może być zaskakująco korzystne.
data DecisionTree i o
= Comparison (i -> Double) Double (DecisionTree i o) (DecisionTree i o)
| Leaf o
runDecisionTree :: DecisionTree i o -> i -> o
runDecisionTree (Comparison f v ifLess ifGreater) i
| f i <= v = runDecisionTree ifLess i
| otherwise = runDecisionTree ifGreater i
runDecisionTree (Leaf o) = o
-- DecisionTree is an encoding of a function, and you can write
-- Functor, Applicative, and Monad instances!
Następnie
classifier :: DecisionTree Stats Classification
classifier =
Comparison curr_linkDensity 0.333333
(Comparison prev_linkDensity 0.555556
(Comparison curr_numWords 16
(Comparison next_numWords 15
(Comparison prev_numWords 4
(Leaf Boilerplate)
(Leaf Content))
(Leaf Content)
...
myślę chcesz 'or', nie' any'. Możesz też użyć '||' zamiast lub 'i' zamiast '&&' s. –