PageSourceSearch

https://zio.dev/assets/js/dce46a57.17ae9e7e.js

js zio.dev collected 2026-10-03 19:27:58 UTC 4,715 bytes, 1 lines download raw bytes

1"use strict";(globalThis.webpackChunkzio_site||=[]).push([[9932],{13795(e,n,t){t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"reference/core/urio","title":"URIO","description":"URIO[R, A] is a type alias for ZIO[R, Nothing, A], which represents an effect that requires an R, and cannot fail, but can succeed with an A.","source":"@site/versioned_docs/version-1.0.18/reference/core/urio.md","sourceDirName":"reference/core","slug":"/reference/core/urio","permalink":"/1.0.18/reference/core/urio","draft":false,"unlisted":false,"editUrl":"https://github.com/zio/zio/edit/series/2.x/versioned_docs/version-1.0.18/reference/core/urio.md","tags":[],"version":"1.0.18","frontMatter":{"id":"urio","title":"URIO"},"sidebar":"overview_sidebar","previous":{"title":"UIO","permalink":"/1.0.18/reference/core/uio"},"next":{"title":"Task","permalink":"/1.0.18/reference/core/task"}}');var r=t(74848),i=t(28453);const o={id:"urio",title:"URIO"},c=void 0,a={},d=[];function l(e){const n={blockquote:"blockquote",code:"code",em:"em",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"URIO[R, A]"})," is a type alias for ",(0,r.jsx)(n.code,{children:"ZIO[R, Nothing, A]"}),", which represents an effect that requires an ",(0,r.jsx)(n.code,{children:"R"}),", and cannot fail, but can succeed with an ",(0,r.jsx)(n.code,{children:"A"}),"."]}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:(0,r.jsx)(n.em,{children:"Note:"})})}),"\n",(0,r.jsxs)(n.p,{children:["In Scala, the ",(0,r.jsx)(n.em,{children:"type alias"})," is a way to give a name to another type, to avoid having to repeat the original type again and again. It doesn't affect the type-checking process. It just helps us to have an expressive API design."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Let's see how the ",(0,r.jsx)(n.code,{children:"URIO"})," type alias is defined:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-scala",children:"type URIO[-R, +A] = ZIO[R, Nothing, A]\n"})}),"\n",(0,r.jsxs)(n.p,{children:["So the ",(0,r.jsx)(n.code,{children:"URIO"})," just equal to ",(0,r.jsx)(n.code,{children:"ZIO"})," which requires ",(0,r.jsx)(n.code,{children:"R"})," and cannot fail because in the Scala the ",(0,r.jsx)(n.code,{children:"Nothing"})," type has no inhabitant, we can't create an instance of type ",(0,r.jsx)(n.code,{children:"Nothing"}),". It succeeds with ",(0,r.jsx)(n.code,{children:"A"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["In following example, the type of ",(0,r.jsx)(n.code,{children:"putStrLn"})," is ",(0,r.jsx)(n.code,{children:"URIO[Console, Unit]"})," which means, it requires ",(0,r.jsx)(n.code,{children:"Console"})," service as an environment, and it succeeds with ",(0,r.jsx)(n.code,{children:"Unit"})," value:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-scala",children:"def putStrLn(line: => String): ZIO[Console, IOException, Unit] =\n  ZIO.accessM(_.get putStrLn line)\n"})}),"\n",(0,r.jsxs)(n.blockquote,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Note:"})," ",(0,r.jsx)(n.em,{children:"Principle of The Least Power"})]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"ZIO"})," data type is the most powerful effect in the ZIO library. It helps us to model various types of workflows. On other hand, the type aliases are a way of subtyping and specializing the ",(0,r.jsx)(n.code,{children:"ZIO"})," type, specific for a less powerful workflow."]}),"\n",(0,r.jsx)(n.p,{children:"Lot of the time, we don't need such a piece of powerful machinery. So as a rule of thumb, whenever we require a less powerful effect, it's better to use the proper specialized type alias."}),"\n",(0,r.jsxs)(n.p,{children:["So there is no need to convert type aliases to the ",(0,r.jsx)(n.code,{children:"ZIO"})," data type, whenever the ",(0,r.jsx)(n.code,{children:"ZIO"})," data type is required, we can use the most precise type alias to fit our workflow requirement."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453(e,n,t){t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.