Не удалось сопоставить ожидаемый тип с фактическим типом - PullRequest
4 голосов
/ 02 мая 2011

Я абсолютный новичок на Хаскеле, и я надеялся, что кто-нибудь сможет мне помочь с этим, потому что я занимаюсь этим часами, и я просто знаю, что я делаю что-то смехотворно глупое.

Предполагается, что программа сканирует файл словаря, чтобы определить все допустимые последовательности слов для набора предложений с удаленными пробелами.

Ex. «внутренне часто» можно разбить на «часто боковыми путями», «размягчить изнутри» и т. д.

Я написал свой прототип на python, и он прекрасно работает (как и моя реализация Java), но для курса требуется реализация на Haskell, и я не могу заставить его работать. Заранее извиняюсь за преступления, которые я совершил против языка и GHC со следующим кодом:

import System.Environment   

main = do
  [dictFilename,sentFilename] <- getArgs  
  dictFile <- readFile dictFilename
  sentFile <- readFile sentFilename

  mapM (\sentence -> solve "" "" sentence (words dictFile)) (words sentFile)

solve prefix header [] dict =
  if (header `elem` dict) 
  then return prefix ++ header
  else return ""

solve prefix header sent dict = do
  let more = solve prefix (header ++ (take 1 sent)) (drop 1 sent) dict

  if (header `elem` dict) 
  then return (solve (prefix ++ header ++ " ") "" sent dict) ++ more
  else return more

1 Ответ

9 голосов
/ 02 мая 2011

Первое, что нужно при исследовании ошибок типов, - это записать сигнатуры типов функций, которые вы знаете.

Здесь, решение может иметь тип

solve :: String -> String -> String -> [String] -> String

или

solve :: String -> String -> String -> [String] -> IO String

В зависимости от того, должен ли он иметь побочные эффекты при вычислении значения.Видя, что вы используете mapM и return повсюду, я думаю, что версия IO, возможно, была предназначена.

Теперь, если вы записываете подпись, вы начинаете получать гораздо более значимые сообщения об ошибках.,Например, вместо этого:

tmp.hs:19:16:
    Couldn't match expected type `Char' with actual type `[Char]'
    Expected type: [Char]
      Actual type: [[Char]]
    In the return type of a call of `solve'
    In the first argument of `return', namely
      `(solve (prefix ++ header ++ " ") "" sent dict)'

, что не имеет особого смысла, вы получите следующее:

tmp.hs:14:8:
    Couldn't match expected type `IO String' with actual type `[a0]'
    In the expression: return prefix ++ header
    In the expression:
      if (header `elem` dict) then return prefix ++ header else return ""
    In an equation for `solve':
        solve prefix header [] dict
          = if (header `elem` dict) then
                  return prefix ++ header
            else
                return ""

, которое точно показывает, где проблема.Приложение-функция имеет самый высокий приоритет в Haskell, поэтому return prefix ++ header эквивалентно (return prefix) ++ header, что, безусловно, не то, что вы имели в виду.

Кстати, если я удаляю IO из возвращаемого типа, удалитевсе return s и изменить вызов, добавив putStrLn, код компилируется и работает!Единственная проблема заключается в том, что он объединяет все возможные предложения в одну строку без каких-либо разделителей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...