2017-01-29 13 views
-1

Этот код возвращает первый коэффициент Integer, начиная с 2 или ничего не возвращает, если он является простым.Just Int to Int

Пример: firstFactorOf 24 возвращает "Только 2"

Пример: firstFactorOf 11 возвращает "Nothing"

Мой вопрос, как бы я возвращающие значение 2, а не "Только 2", если есть или вернуть значение x, если нет фактора.

firstFactorOf x 
    | m == Nothing = m 
    | otherwise = m 
    where m =(find p [2..x-1]) 
      p y = mod x y == 0 

//RETURNS: 
ghci> firstFactorOf 24 
Just 2 
ghci> firstFactorOf 11 
Nothing 
+0

Что должно быть возвращено в случае «Ничего»? –

+0

Вопрос может быть интерпретирован как «Как включить в себя предположение, что' x' имеет первый фактор (так что я могу избежать «Может быть, вообще») или «Почему Haskell не имеет понятия немаркированных союзов». Что он? – Alec

+0

x должен быть возвращен. –

ответ

-1
import Data.List 
import Data.Maybe 

firstFactorOf x 
    | m == Nothing = x 
    | otherwise = fromJust m 
    where m =(find p [2..x-1]) 
      p y = mod x y == 0 

Это было то, что я был после. Не знаете, почему вы, ребята, сделали это настолько сложным.

4

Haskell является статически типизированным, а это означает, что вы можете определить функцию Maybe a -> a, но вопрос в том, что делать с Nothing случае.

Haskell имеет две функции, которые могут быть полезны здесь: fromMaybe и fromJust:

fromMaybe :: a -> Maybe a -> a 
fromJust :: Maybe a -> a 

fromJust просто предполагает, что вы всегда будете предоставлять ему Just x и вернуть x, в другом случае, это будет бросаться исключение.

fromMaybe с другой стороны, два параметра, первый - a является «по умолчанию случай» значение, которое должно быть возвращено в случае Nothing. Далее дается Maybe a, а в случае, если возвращается Just x, возвращается x. В другом случае (Nothing), как указано перед возвратом по умолчанию.

В своем комментарии вы говорите, что x следует вернуть в случае отсутствия такого фактора. Поэтому я предлагаю вам определить новую функцию:

firstFactorOfJust :: Integral a => a -> a 
firstFactorOfJust x = fromMaybe x $ firstFactorOf x 

Так эта функция firstFactorOfJust вызывает вашу firstFactorOf функции и, если результат Nothing, x будут возвращены. В другом случае будет возвращен результат firstFactorOf (но только часть Integral, а не часть Just ...).

EDIT (упрощенный)

Основываясь на собственном ответе, что если бы намерены упростить вещи немного, у меня была идея, что вы можете упростить это немного больше:

firstFactorOf x | Just z <- find ((0 ==) . mod x) [2..x-1] = z 
       | otherwise = x 

и поскольку мы все являемся поклонниками оптимизации, вы уже можете остановить после sqrt(x) итераций (хорошо известная оптимизация при первичной проверке):

isqrt :: Int -> Int 
isqrt = floor . sqrt . fromIntegral 

firstFactorOf x | Just z <- find ((0 ==) . mod x) [2..isqrt x] = z 
       | otherwise = x 

упрощенного вопрос

По какой-то причине был какой-то особенно сложный аспект в вашем вопросе:

firstFactorOf x 
    | m == Nothing = m 
    | otherwise = m 
    where m =(find p [2..x-1]) 
      p y = mod x y == 0

Почему вы используете охранник, чтобы провести различие между двумя случаями, которые производят один и тот же выход?Вы можете сложить это в:

firstFactorOf x = m 
    where m = (find p [2..x-1]) 
      p y = mod x y == 0

и еще дальше:

firstFactorOf x = find p [2..x-1] 
       where p y = mod x y == 0
+0

Это было слишком сложно. Я разместил свое собственное решение, которое отвечает на вопрос так, как его спрашивали. Зачем предлагать новую функцию для такой простой задачи? –

+0

Вам не нужно предлагать новую функцию. Вы могли бы, например, не возвращать 'Nothing', а просто' x'. Ваш вопрос был озаглавлен «Just Int» для 'Int'» ... По-моему, вы ищете «конверсию». Это то, что делают люди, когда * конвертировать * вещь из * одного типа * в * другое *. Кроме того, считается, что * elegant * возвращает 'Nothing', если, например, поиск завершился неудачно. –

+0

Наконец, похоже, что вы просто скопировали функцию из учебника, не зная, как это работает (иначе вы, вероятно, не позволили бы ему возвращать «ничего» для начала) ... –

1

Если вы хотите, чтобы вернуть первый фактор x или x, то это должно работать:

firstFactorOf x = 
    let 
    p y = mod x y == 0 
    m = (find p [2..x-1]) 
    in 
    fromMaybe x m