diff --git a/cherry-core-alpha.cabal b/cherry-core-alpha.cabal
--- a/cherry-core-alpha.cabal
+++ b/cherry-core-alpha.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                cherry-core-alpha
-version:             0.1.0.0
+version:             0.2.0.0
 synopsis:            The core library for Cherry Haskell.
 description:         The core library for Cherry Haskell, including a standard fuctions, server, and json parsing.
 license:             BSD3
@@ -72,6 +72,7 @@
     binary,
     bytestring,
     containers >=0.6 && <0.7,
+    directory,
     ghc-prim,
     base64-bytestring,
     wai-middleware-static,
diff --git a/src/File.hs b/src/File.hs
--- a/src/File.hs
+++ b/src/File.hs
@@ -12,13 +12,14 @@
 
 -}
 
-module File (read, write) where
+module File (Path, read, write) where
 
 import qualified List
 import qualified String
 import qualified Internal.Task as Task
 import qualified Internal.Utils as U
 import qualified Data.Text.IO as IO
+import qualified System.Directory as Directory
 import Prelude (return, getContents)
 import Basics
 import Maybe (Maybe (..))
@@ -32,16 +33,22 @@
 import Char (Char)
 
 
+type Path
+  = String
+
+
 {-| -}
-write :: String -> String -> Task x ()
+write :: Path -> String -> Task x ()
 write filename string =
   Task.Task <| do
+    let dir = String.split "/" filename |> List.reverse |> List.drop 1 |> List.reverse |> String.join "/"
+    Directory.createDirectoryIfMissing True (String.toList dir)
     IO.writeFile (String.toList filename) (String.toTextUtf8 string)
     return (Ok ())
 
 
 {-| -}
-read :: String -> Task x String
+read :: Path -> Task x String
 read filename =
   Task.Task <| do
     contents <- IO.readFile (String.toList filename)
diff --git a/src/Internal/Task.hs b/src/Internal/Task.hs
--- a/src/Internal/Task.hs
+++ b/src/Internal/Task.hs
@@ -13,6 +13,7 @@
 import qualified GHC.Stack as Stack
 import qualified Internal.Shortcut as Shortcut
 import qualified Control.Concurrent.MVar as MVar
+import qualified Control.Concurrent.Async as Async
 import qualified System.IO
 import qualified List
 import qualified Dict
@@ -182,4 +183,9 @@
   onError (fail << func) task
 
 
+{-| Run tasks in parallel.
 
+-}
+parallel :: List (Task x a) -> Task x (List a)
+parallel tasks =
+  Task <| Shortcut.map P.sequence (Async.forConcurrently tasks toIO)
diff --git a/src/Task.hs b/src/Task.hs
--- a/src/Task.hs
+++ b/src/Task.hs
@@ -17,7 +17,7 @@
   ( Task, Task.perform, Task.attempt
 
     -- * Chains
-  , andThen, Task.succeed, Task.fail, Task.sequence
+  , andThen, Task.succeed, Task.fail, Task.sequence, Task.parallel
 
     -- * Maps
   , map, map2, map3, map4, map5, map6
