Преобразувайте функция на Haskell в SML

Опитвам се да конвертирам функция на Haskell, която показва булева формула, в SML функция.

Функцията:

data Formula
    = Atom String
    | Neg  Formula
    | Conj Formula Formula
    | Disj Formula Formula

precedence :: Formula -> Int
precedence Atom{} = 4
precedence Neg {} = 3
precedence Conj{} = 2
precedence Disj{} = 1

displayPrec :: Int -> Formula -> String
displayPrec dCntxt f = bracket unbracketed where
dHere       = precedence f
recurse     = displayPrec dHere
unbracketed = case f of
    Atom s   -> s
    Neg  p   -> "~ " ++ recurse p
    Conj p q -> recurse p ++ " & " ++ recurse q
    Disj p q -> recurse p ++ " | " ++ recurse q
bracket
    | dCntxt > dHere = \s -> "(" ++ s ++ ")"
    | otherwise      = id

display :: Formula -> String
display = displayPrec 0

Стигнах дотам да го преведа на SML:

fun precedence(operator) = 
    case operator of
        Atom a => 4 
      | Neg p => 3
      | Conj(p,q) => 2
      | Disj(p,q) => 1

fun displayPrec dCntxt f = 
   let 
      val dHere = precedence f
      val recurse = displayPrec dHere

      val unbracketed = case f of 
                 Atom a => a
               | Neg p => "~ " ^ recurse p
               | Conj(p,q)=>(recurse p) ^ " & " ^ (recurse q)
               | Disj(p,q)=>(recurse p) ^ " | " ^ (recurse q)

      (* missing bracket function *)               

   in
      (* bracket *) unbracketed 
   end

Функцията без скоби работи. Показва формулата без скоби. Единственото нещо, което все още липсва, е функцията за скоби, която не знам какво прави и как да я преведа на SML. Може ли някой по-опитен да ми помогне с това?


person TheAptKid    schedule 06.12.2013    source източник


Отговори (1)


Това би било

val bracket =
  if dCntxt > dHere
  then fn s => "(" ^ s ^ ")"
  else fn x => x

Функцията сравнява нивото на приоритет на вашия контекст с нивото на приоритет на външния оператор на вашия израз и решава дали да вмъкне чифт скоби около дадения низ или не.

person kosmikus    schedule 06.12.2013
comment
Това може да се подобри чрез използване на List.concat в SML, за да се избегне повторение на s два пъти с помощта на ^ - person Mokosha; 07.12.2013