Django - как создать файл и сохранить его в FileField модели?

Как указывали другие, в Haskell каждое значение является неизменным и нет объекта. Чтобы указать уникальный узел, вам нужно либо его структурировать (например, первый узел в связанном списке, который содержит 1), либо дать каждому узлу дополнительный тэг каким-либо образом (имитируя, что происходит в императивном мире), чтобы мы могут различать их.

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

И более подробно о том, «чтобы каждый узел добавлял дополнительный тег»:

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

-- | bumps counter
genId :: (Monad m, Functor m, Enum e) => StateT e m e
genId = get <* modify succ

-- | given a value, initializes a new node value
newNode :: (Monad m, Functor m, Enum e) => a -> StateT e m (a,e)
newNode x = genId >>= return . (x,)

И если вы хотите сделать существующий связанный список, нам нужно пройти через него и дать каждому значению узла тег, чтобы сделать его объектом:

-- | tags the llnked list with an extra value
tagged :: (Traversable f, Enum e, Monad m, Functor m)
       => f a -> StateT e m (f (a,e))
tagged = traverse newNode

И вот полная демоверсия, это выглядит неудобно Maybe "a little":

{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable, TupleSections #-}
import Control.Applicative
import Control.Monad.State hiding (mapM_)
import Data.Traversable
import Data.Foldable
import Prelude hiding (mapM_)

data LL a = Empty | Node a (LL a)
    deriving (Show, Eq, Functor, Foldable, Traversable)

-- | bumps counter
genId :: (Monad m, Functor m, Enum e) => StateT e m e
genId = get <* modify succ

-- | given a value, initializes a new node value
newNode :: (Monad m, Functor m, Enum e) => a -> StateT e m (a,e)
newNode x = genId >>= return . (x,)

example :: LL Int
example = Node 1 (Node 2 (Node 3 (Node 1 Empty)))

-- | tags the llnked list with an extra value
tagged :: (Traversable f, Enum e, Monad m, Functor m)
       => f a -> StateT e m (f (a,e))
tagged = traverse newNode

insertAfter :: (a -> Bool) -> a -> LL a -> LL a
insertAfter cond e ll = case ll of
    Empty -> Empty
    Node v vs -> Node v (if cond v
                           then Node e vs
                           else insertAfter cond e vs)

demo :: StateT Int IO ()
demo = do
    -- ll1 = Node (1,0) (Node (2,1) (Node (3,2) (Node (1,3) Empty)))
    ll1 <- tagged example
    nd <- newNode 10
    let tagIs t = (== t) . snd
        ll2 = insertAfter (tagIs 0) nd ll1
        -- ll2 = Node (1,0) (Node (10,4) (Node (2,1) (Node (3,2) (Node (1,3) Empty))))
        ll3 = insertAfter (tagIs 3) nd ll1
        -- ll3 = Node (1,0) (Node (2,1) (Node (3,2) (Node (1,3) (Node (10,4) Empty))))
    liftIO $ mapM_ print [ll1,ll2,ll3]

main :: IO ()
main = evalStateT demo (0 :: Int)

В этой демонстрации tagIs по существу делает вещь «равенство объекта», потому что ее интересует только дополнительный тег, который мы добавили раньше. Обратите внимание на то, что я обманул, чтобы указать два узла со своими «значениями», являющимися 1: один помечен 0, а другой отмечен 3. Перед запуском программы невозможно определить, каков будет фактический тег. (Точно так же, как жесткое кодирование значения указателя и надеемся, что это сработает). В более реалистичной настройке вам понадобится другая функция для сканирования через связанный список и получения списка тегов с определенным значением (в этом примере, если вы просматриваете связанный список, чтобы найти все узлы с «значением» 1, с которым вы бы [0,3] работали.

«Равенство объектов» больше похоже на концепцию с императивных языков программирования, который предполагает, что есть распределители, предлагающие «ссылки» или «указатели», чтобы мы могли говорить о «равенстве объектов». Мы должны имитировать этот распределитель, я думаю, что это то, что делает функциональное программирование немного неудобным для решения проблемы.

91
задан Greg 22 September 2011 в 12:49
поделиться