Надлежащий способ импортировать вещи, уже определенные во Вводной части в Haskell

Я пытаюсь определить Складной экземпляр в Haskell, и у меня есть некоторая проблема с импортом.

Поэтому первая попытка: модуль MyList, где

import Data.Foldable

data MyList a = MyList [a]

instance Foldable (MyList) where
  foldr f b (MyList as) = foldr f b as

Результат (нормальный, но раздражающий)

Неоднозначное возникновение 'foldr'

Так, я предполагаю, что должен скрыть его от Вводной части: модуль MyList, где

import Prelude hiding (foldr)
import Data.Foldable

data MyList a = MyList [a]

instance Foldable (MyList) where
  foldr f b (MyList as) = foldr f b as

Эта компиляция, я загружаюсь в ghci и пробую некоторый основной материал:

*MyList> foldr (:) "" (MyList "hello")
"hello"
*MyList> foldl (flip (:)) "" (MyList "hello")

<interactive>:1:0:
    Ambiguous occurrence `foldl'
    It could refer to either `Prelude.foldl', imported from Prelude at MyList.hs:4:0-28
                          or `Data.Foldable.foldl', imported from Data.Foldable at MyList.hs:5:0-19
*MyList>

Так foldr работы, но foldl не делает. Мой первый вопрос

Сделайте я должен скрыть вручную каждый метод, определенный в Данных. Складной из Вводной части их хороший способ сделать это?

.

Для предотвращения этой проблемы я пытался сделать квалифицированный импорт: модуль MyList, где

import qualified  Data.Foldable as F

data MyList a = MyList [a]

instance F.Foldable (MyList) where
  foldr f b (MyList as) = foldr f b as

Кажется, компилирует в ghc, но

*MyList> foldr (:) "" (MyList "hello")

<interactive>:1:14:
    Couldn't match expected type `[Char]'
           against inferred type `MyList Char'
    In the third argument of `foldr', namely `(MyList "hello")'
    In the expression: foldr (:) "" (MyList "hello")
    In the definition of `it': it = foldr (:) "" (MyList "hello")

foldr не найден, но удивительно работы F.foldr в ghci.

*MyList> F.foldr (:) "" (MyList "hello")
"hello"

Но в ghci только, если я пытаюсь импортировать MyList в файле, foldr, F.foldr, MyList. F.foldr и MyList.foldr не работают.

Почему это работает в ghci, но не в реальном?

Я предполагаю, что должен импортировать Данные. Складной снова (и снова в каждом использовании файлов MyList)

Есть ли лучший способ сделать это (как экспорт Данных. Складной в MyList)?

(Я - новичок в Haskell и особенно с модулями),


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

Что обычная практика должна иметь дело с такой проблемой?

Спасибо за Вас справка.

15
задан Don Stewart 19 April 2011 в 03:22
поделиться

4 ответа

Вы можете сделать модуль Prelude', который экспортирует только то, что вам нужно. Затем вы могли бы начать свой настоящий модуль следующим образом:

import Prelude ()
import Prelude'
import Data.Foldable

Конечно, вам придется выполнять работу в Prelude', но, по крайней мере, он будет многоразовым.

Уточнение:

Prelude'.hs:

module Prelude' (
    id
  , Num (..)
  , everthing you want exported for your 'customized' prelude module goes in this list
  ) where
2
ответ дан 1 December 2019 в 03:52
поделиться

Я перечитал ваш вопрос и некоторые из ваших комментариев, и я думаю, что самое близкое вы можете понять, что вы want выглядит примерно так:

module MyList
  (
    module Data.Foldable,
    MyList(..)
  )
where


import Data.Foldable
import Prelude (($))


data MyList a = MyList [a]

instance Foldable (MyList) where
    foldr f b (MyList as) = foldr f b as

По сути, MyList реэкспортирует модуль Data.Foldable , так что кому-то, использующему ваш модуль, не придется импортировать данные. Снова складывается, но ... ей придется скрыть некоторые функции из Prelude .

module Main (main) where


import Prelude hiding (foldr)
import MyList


mySum :: MyList Int -> Int
mySum = foldr (+) 0

main :: IO ()
main = putStrLn . show . mySum $ MyList [1,2,3]

ИМХО, это хорошо. Не стоит решать, как и что кто-то импортирует в свои собственные модули.

2
ответ дан 1 December 2019 в 03:52
поделиться

Что касается неявного импорта Prelude , вы можете добавить следующую языковую прагму, а затем явно импортировать вещи из Prelude , но это может оказаться уродливее, чем просто скрытие вещей из Prelude или использование квалифицированного импорта Data.Foldable .

{-# LANGUAGE NoImplicitPrelude #-}

import Prelude (someFunction)

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

{-# LANGUAGE NoImplicitPrelude #-}
module Main (main) where

-- we import fromInteger although it's not explicitly used
import Prelude (Int, foldl, fromInteger, (+), putStrLn, (.), ($), IO, show)

sum :: [Int] -> Int
sum = foldl (+) 0

main :: IO ()
main = putStrLn . show $ sum [1,2,3]

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

6
ответ дан 1 December 2019 в 03:52
поделиться

Почему это работает в ghci, но не работает на самом деле?

Поскольку в сеансе GHCi вы вводили выражения в контексте модуля MyList , поэтому F.foldr находился в области действия, но если вы импортируете MyList в другой модуль, тогда только имена, экспортированные из MyList , и другие модули, которые вы импортировали, попадают в область видимости.

Ваше предположение верно - в каждом модуле, использующем Data.Foldable.foldr , вы должны

import qualified Data.Foldable as F

Имена, экспортируемые модулем, неквалифицированы; квалификация этих имен решается при импорте модуля.

На протяжении многих лет выдвигались предложения разрешить экспорт полных имен, но на сегодняшний день ничего не реализовано.

7
ответ дан 1 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: